php5.6-和php5.6 CURL 上传文件的一个坑

php
赞赏 2016-12-09

踩到一个php 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);
  • 显然上面代码 采用 file => @ . realpath(xxx) 方式看似没问题,也是大家常用上传方法。
  • 但是php5.6 @realpath 这样方法突然失效,server 接到不到post 的临时文件。
  • 问题在 stackoverflow 上找到了答案

Actually I found the answer while starting the question. There is a new Variable included with curl in PHP 5.5: CURLOPT_SAFE_UPLOAD this is set to false by default in PHP 5.5 and is switched to a default of true in PHP 5.6.

This will prevent the '@' upload modifier from working for security reasons - user input could contain malicious upload requests. You can use the CURLFile class to upload files while CURLOPT_SAFE_UPLOAD is set to true or (if you're sure your variables are safe you can switch the CURLOPT_SAFE_UPLOAD to false manually):

curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);

PHP 5.5另外引入了CURL_SAFE_UPLOAD选项,可以强制PHP的cURL模块拒绝旧的@语法,仅接受CURLFile式的文件。5.5的默认值为false,5.6的默认值为true。Are you fuck kidding me?!

解决方法

  • 最优解当然是保持php各环境版本统一,建议是最新稳定版
  • 次优解是:
    if (class_exists('\CURLFile')) {
    $field = array('fieldname' => new \CURLFile(realpath($filepath)));
    } else {
    $field = array('fieldname' => '@' . realpath($filepath));
    }

    代码应该回归本源。我们的实际需求其实是:有CURLFile就优先采用,没有再退化到传统@语法

  • 最lowB的解:
    if (version_compare(phpversion(), '5.4.0') >= 0)

    版本号莫名其妙的出现在代码之中,不查半天PHP手册和更新历史,很难明白作者被卡在了哪个功能的变更上。

查找官方根源

  • 打开http://php.net/manual/zh/function.curl-setopt.php(中文版) ctrl+F CURLOPT_SAFE_UPLOAD, 没找到!
  • 打开http://php.net/manual/en/function.curl-setopt.php (英文版) 同样查找 终于找到了
  • 果然如上所说php5.6默认不支持@ curl上传了,用curlFile代替了。啃爹的是中文文档没记录!@phpGroup @鸟哥 管不管?
登陆后阅读全文
阅读 2439 赞赏 0 有用 11 没用 0 收藏 3 分享

   


作者声明:本篇文章系本人原创,欢迎分享,但未经许可,谢绝转载。

0 条留言

有经验的老司机的头像

有经验的老司机

年轻人,走!我带你。

相关文章

Linux php-fpm报错:allow_call_time_pass_reference

如何配置php显示错误信息?

6款程序员必备的开源中文汉字拼音转换及处理工具 (PHP Java .net)

PHP Fatal error: Allowed memory size of bytes exhausted

Linux 服务器如何隐藏 PHP 版本号?

PHP 程序无法识别短标签

改了php.ini中的open_basedir仍报错open_basedir restriction in effect

原来这条命令可以让我们快速找到php.ini的位置

php call_user_fun Call-time pass-by-reference has been remov

php.ini 设置了 error_log 为什么不生效?

有料推荐

这世界欠我一个这样的老公!

高校学生模仿“世界名画”摆拍,可以说是戏精本精了

iPhone X 跌破发行价,苏宁200亿入股恒大 | 财经日日评

果然是高手!这次在日本,特朗普竹杠敲得不是一般狠

资深黄牛现身说法:iPhone X价格秒变不停,就像炒股一样

长一样的双胞胎也能识别?蚂蚁金服发布「眼纹识别」技术

苏联是怎么被阿富汗拖垮的?

美团或入局「分时租赁」共享汽车,王兴要大笔投入「泛出行」领域了? | 36氪独家

你或许被“一盘番茄炒蛋”刷屏了,但有人辛酸,有人质疑

iPhone X发售前夜,黄牛与苹果公司的不安

他的文章

电脑无线连接安卓手机 进入android命令行模式(完胜adb shell数据线连接方式)

iTerm2配置clone session功能

如何科学上网(翻墙)

php5.6-和php5.6 CURL 上传文件的一个坑

如何修改lumen storage path/log path

php.ini 设置了 error_log 为什么不生效?

IP查询二分法的运用

iframe 的高度自适应 iframe 内容页面的高度解决方案

手机扫一扫
分享文章