从 PHP 5.5 升级到 5.6 后,cURL 文件上传不再起作用
Posted
技术标签:
【中文标题】从 PHP 5.5 升级到 5.6 后,cURL 文件上传不再起作用【英文标题】:cURL file uploads not working anymore after upgrade from PHP 5.5 to 5.6 【发布时间】:2014-11-14 01:27:41 【问题描述】:从 php 5.5 升级到 5.6 后,我的 cURL 上传失败:
$aPost = array(
'file' => "@".$localFile,
'default_file' => 'html_version.html',
'expiration' => (2*31*24*60*60)
)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiurl);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_BUFFERSIZE, 128);
curl_setopt($ch, CURLOPT_POSTFIELDS, $aPost);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$sResponse = curl_exec ($ch);
目标系统上的文件似乎是空的。
【问题讨论】:
你是如何升级的? curl 模块是否包含在更新中?这是什么操作系统?您是否消除了导致问题的其他原因? 是的,curl 正在工作 - 文件是空的(字符串被发送到目标系统而不是文件)。操作系统是 CentOS,在更新之间没有改变。 (在添加答案时添加了我的评论) 【参考方案1】:其实我在开始提问的时候就找到了答案。 PHP 5.5 中的 curl 包含一个新变量:CURLOPT_SAFE_UPLOAD
,在 PHP 5.5 中默认设置为 false
,在 PHP 5.6 中切换为默认 true
。
出于安全原因,这将阻止“@”上传修饰符工作 - 用户输入可能包含恶意上传请求。当CURLOPT_SAFE_UPLOAD
设置为true
时,您可以使用CURLFile
类上传文件,或者(如果您确定您的变量是安全的,您可以手动将CURLOPT_SAFE_UPLOAD
切换为false
):
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
以下是让我找到正确方向的信息来源:http://comments.gmane.org/gmane.comp.php.devel/87521
在更改的函数中也提到了:http://php.net/manual/en/migration56.changed-functions.php 但不是在向后不兼容的变化中,真的把我绊倒了......
【讨论】:
请注意,将 CURLOPT_SAFE_UPLOAD 设置为 false 会在 PHP 5.5 或更高版本中发出弃用消息。而不是"@" . $localFile
,只需使用new \CURLFile($localFile)
。这并不难。当然,这个类在 PHP 5.4 中不可用。
看起来只是将CURLOPT_SAFE_UPLOAD
设置为 false 在 PHP 5.6 中不起作用。使其工作的正确且唯一的方法是@deepti-gehlot 建议的方法【参考方案2】:
只需对 PHP 5.5 或更高版本进行以下更改
不要使用"@" . $localFile
,而是使用new CurlFile($localFile)
设置
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true);
【讨论】:
你拯救了我的一天!【参考方案3】:包括运行时检查以使您的代码也与下面的较低版本兼容
$aPost = array(
'default_file' => 'html_version.html',
'expiration' => (2*31*24*60*60)
)
if ((version_compare(PHP_VERSION, '5.5') >= 0))
$aPost['file'] = new CURLFile($localFile);
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true);
else
$aPost['file'] = "@".$localFile;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiurl);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_BUFFERSIZE, 128);
curl_setopt($ch, CURLOPT_POSTFIELDS, $aPost);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$sResponse = curl_exec ($ch);
【讨论】:
$post_array 变量好像名字不好,不应该是$aPost吗? 抱歉,忘记重命名变量了。非常感谢。 :)以上是关于从 PHP 5.5 升级到 5.6 后,cURL 文件上传不再起作用的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 从 5.5 升级到 5.6 到 5.7:未捕获 ReferenceError: axios is not defined