从 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

MySQL 从 5.5 升级到 5.6,日期空条件失败

MySQL从5.5升级到5.6,TIMESTAMP的变化

升级到5.6后Mysql在所有字段中搜索字符串变慢

PHP 5.6 如何使用 CURL 上传文件

将 Laravel 5.5 升级到 5.6 错误