首页 后端开发 php教程 curl上传文件版本差异问题解析

curl上传文件版本差异问题解析

Mar 05, 2018 am 10:22 AM
curl 差异 版本

=前端post表单上传文件后,在后端收到文件后转发post到图片服务器。于是使用了curl上传,利用’@文件路径的方式上传’ 

代码如下

<?php
    if($_FILES[&#39;video&#39;][&#39;size&#39;]>0){        $data = array('video'=>$_FILES['video']['tmp_name']);         $ch = curl_init();         $url="test.php";
        // 设置URL和相应的选项
        curl_setopt($ch, CURLOPT_URL, $url);
        //启用时会将头文件的信息作为数据流输出。 
        curl_setopt($ch, CURLOPT_HEADER, 0);
        //将curl_exec()获取的信息以字符串返回,而不是直接输出
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);         $res = curl_exec($ch);
        // 抓取URL并把它传递给浏览器
        curl_exec($ch);
        // 关闭cURL资源,并且释放系统资源
        curl_close($ch);

   }
登录后复制
登录后复制

测试机的php版本是5.2这断代码没问题,但是放到线上,$_FILES变量死活收不到值。然后仔细观察,在$_POST里面收到了$_POST[‘video’]=’@/tmp/phps12d63’;这就比较奇怪了,第一反应是Content-Type没有正常传送,上传文件的Content-Type应该是’multipart/form-data’ ,这种情况应该是‘application/x-www-form-urlencoded’。然后在图片服务器上打印$_SERVER[‘HTTP_CONTENT_TYPE’]变量,发现就是‘multipart/form-data’。
查看手册,发现了如果是CURLOPT_POSTFIELDS的传递参数是数组,Content-Type头将会被设置成multipart/form-data。
然后还有一个神奇的CURLOPT_SAFE_UPLOAD参数,在php5.5.0中添加,默认值是false,5.6.0默认为ture,

CURLOPT_SAFE_UPLOAD
 TRUE 禁用 @ 前缀在 CURLOPT_POSTFIELDS 中发送文件。 意味着 @ 可以在字段中安全得使用了。 可使用
 CURLFile 作为上传的代替。

而CURLOPT_POSTFIELDS参数说明

CURLOPT_POSTFIELDS
 全部数据使用HTTP协议中的 “POST” 操作来发送。 要发送文件,在文件名前面加上@前缀并使用完整路径。 文件类型可在文件名后以 ‘;type=mimetype’ 的格式指定。 这个参数可以是 urlencoded 后的字符串,类似’para1=val1¶2=val2&…’,也可以使用一个以字段名为键值,字段数据为值的数组。 如果value是一个数组,Content-Type头将会被设置成multipart/form-data。 从 PHP 5.2.0 开始,使用 @ 前缀传递文件时,value 必须是个数组。 从 PHP 5.5.0 开始, @ 前缀已被废弃,文件可通过 CURLFile 发送。 设置 CURLOPT_SAFE_UPLOAD 为 TRUE 可禁用 @ 前缀发送文件,以增加安全性。

查看版本,果然测试环境是php5.3,而线上测试环境是5.6,也是就是说CURLOPT_SAFE_UPLOAD默认为true,禁用了@ 上传,@就是普通字符串了。而从5.5开始@前缀上传文件已经被废弃。大于5.5版本需使用CURLFile 上传。最后兼容方案小于5.5使用@前缀,大于5.5使用CURLFile,在小于5.5的版本是用@上传还可以添加额外的参数;filename=文件名;type=mime类型

<?php
//curl_file_create是函数的别名CURLFile::__construct() if (!function_exists('curl_file_create')) {
    function curl_file_create($filename, $mimetype = '', $postname = '') {
        return "@$filename;filename="
            . ($postname ?: basename($filename))
            . ($mimetype ? ";type=$mimetype" : '');
    }
}
登录后复制
登录后复制

最后代码为

<?php
    if($_FILES[&#39;video&#39;][&#39;size&#39;]>0){        $data = array('video'=>$_FILES['video']['tmp_name']);         $ch = curl_init();         $url="test.php";
        // 设置URL和相应的选项
        curl_setopt($ch, CURLOPT_URL, $url);
        //启用时会将头文件的信息作为数据流输出。 
        curl_setopt($ch, CURLOPT_HEADER, 0);
        //将curl_exec()获取的信息以字符串返回,而不是直接输出
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);        $data['video']=curl_file_create($_FILES['video']['tmp_name'],'video/mp4',$_FILES['video']['name']);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);         $res = curl_exec($ch);
        // 抓取URL并把它传递给浏览器
        curl_exec($ch);
        // 关闭cURL资源,并且释放系统资源
        curl_close($ch);

   }
登录后复制
登录后复制

总结,遇到问题,要先冷静分析,然后在仔细阅读手册。

周五遇到一个问题,前端post表单上传文件后,在后端收到文件后转发post到图片服务器。于是使用了curl上传,利用’@文件路径的方式上传’
代码如下

<?php
    if($_FILES[&#39;video&#39;][&#39;size&#39;]>0){        $data = array('video'=>$_FILES['video']['tmp_name']);         $ch = curl_init();         $url="test.php";
        // 设置URL和相应的选项
        curl_setopt($ch, CURLOPT_URL, $url);
        //启用时会将头文件的信息作为数据流输出。 
        curl_setopt($ch, CURLOPT_HEADER, 0);
        //将curl_exec()获取的信息以字符串返回,而不是直接输出
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);         $res = curl_exec($ch);
        // 抓取URL并把它传递给浏览器
        curl_exec($ch);
        // 关闭cURL资源,并且释放系统资源
        curl_close($ch);

   }
登录后复制
登录后复制

测试机的php版本是5.2这断代码没问题,但是放到线上,$_FILES变量死活收不到值。然后仔细观察,在$_POST里面收到了$_POST[‘video’]=’@/tmp/phps12d63’;这就比较奇怪了,第一反应是Content-Type没有正常传送,上传文件的Content-Type应该是’multipart/form-data’ ,这种情况应该是‘application/x-www-form-urlencoded’。然后在图片服务器上打印$_SERVER[‘HTTP_CONTENT_TYPE’]变量,发现就是‘multipart/form-data’。
查看手册,发现了如果是CURLOPT_POSTFIELDS的传递参数是数组,Content-Type头将会被设置成multipart/form-data。
然后还有一个神奇的CURLOPT_SAFE_UPLOAD参数,在php5.5.0中添加,默认值是false,5.6.0默认为ture,

CURLOPT_SAFE_UPLOAD
 TRUE 禁用 @ 前缀在 CURLOPT_POSTFIELDS 中发送文件。 意味着 @ 可以在字段中安全得使用了。 可使用
 CURLFile 作为上传的代替。

而CURLOPT_POSTFIELDS参数说明

CURLOPT_POSTFIELDS
 全部数据使用HTTP协议中的 “POST” 操作来发送。 要发送文件,在文件名前面加上@前缀并使用完整路径。 文件类型可在文件名后以 ‘;type=mimetype’ 的格式指定。 这个参数可以是 urlencoded 后的字符串,类似’para1=val1¶2=val2&…’,也可以使用一个以字段名为键值,字段数据为值的数组。 如果value是一个数组,Content-Type头将会被设置成multipart/form-data。 从 PHP 5.2.0 开始,使用 @ 前缀传递文件时,value 必须是个数组。 从 PHP 5.5.0 开始, @ 前缀已被废弃,文件可通过 CURLFile 发送。 设置 CURLOPT_SAFE_UPLOAD 为 TRUE 可禁用 @ 前缀发送文件,以增加安全性。

查看版本,果然测试环境是php5.3,而线上测试环境是5.6,也是就是说CURLOPT_SAFE_UPLOAD默认为true,禁用了@ 上传,@就是普通字符串了。而从5.5开始@前缀上传文件已经被废弃。大于5.5版本需使用CURLFile 上传。最后兼容方案小于5.5使用@前缀,大于5.5使用CURLFile,在小于5.5的版本是用@上传还可以添加额外的参数;filename=文件名;type=mime类型

<?php
//curl_file_create是函数的别名CURLFile::__construct() if (!function_exists('curl_file_create')) {
    function curl_file_create($filename, $mimetype = '', $postname = '') {
        return "@$filename;filename="
            . ($postname ?: basename($filename))
            . ($mimetype ? ";type=$mimetype" : '');
    }
}
登录后复制
登录后复制

最后代码为

<?php
    if($_FILES[&#39;video&#39;][&#39;size&#39;]>0){        $data = array('video'=>$_FILES['video']['tmp_name']);         $ch = curl_init();         $url="test.php";
        // 设置URL和相应的选项
        curl_setopt($ch, CURLOPT_URL, $url);
        //启用时会将头文件的信息作为数据流输出。 
        curl_setopt($ch, CURLOPT_HEADER, 0);
        //将curl_exec()获取的信息以字符串返回,而不是直接输出
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);        $data['video']=curl_file_create($_FILES['video']['tmp_name'],'video/mp4',$_FILES['video']['name']);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);         $res = curl_exec($ch);
        // 抓取URL并把它传递给浏览器
        curl_exec($ch);
        // 关闭cURL资源,并且释放系统资源
        curl_close($ch);

   }
登录后复制
登录后复制

相关推荐:

php通过CURL上传文件

php curl上传文件的简单例子

post - php curl上传文件如何像表单一样指定其name值

以上是curl上传文件版本差异问题解析的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何快速查看numpy版本 如何快速查看numpy版本 Jan 19, 2024 am 08:23 AM

Numpy是Python中一个重要的数学库,它提供了高效的数组操作和科学计算函数,被广泛应用于数据分析、机器学习、深度学习等领域。在使用numpy过程中,我们经常需要查看numpy的版本号,以便确定当前环境所支持的功能。本文将介绍如何快速查看numpy版本,并提供具体的代码示例。方法一:使用numpy自带的__version__属性numpy模块自带一个__

如何查看maven版本 如何查看maven版本 Jan 17, 2024 pm 05:06 PM

查看maven版本的方法:1、使用命令行;2、查看环境变量;3、使用IDE;4、查看pom.xml文件。详细介绍:1、使用命令行,在命令行中输入"mvn -v"或"mvn --version",然后按回车,这将显示Maven的版本信息以及Java的版本信息;2、查看环境变量,在某些系统上,可以查看环境变量来找到Maven的版本信息,在命令行中输入命令,然后回车等等。

Linux下更新curl版本教程! Linux下更新curl版本教程! Mar 07, 2024 am 08:30 AM

在Linux下更新curl版本,您可以按照以下步骤进行操作:检查当前curl版本:首先,您需要确定当前系统中安装的curl版本。打开终端,并执行以下命令:curl--version该命令将显示当前curl的版本信息。确认可用的curl版本:在更新curl之前,您需要确定可用的最新版本。您可以访问curl的官方网站(curl.haxx.se)或相关的软件源,查找最新版本的curl。下载curl源代码:使用curl或浏览器,下载您选择的curl版本的源代码文件(通常为.tar.gz或.tar.bz2

如何轻松查看Oracle的安装版本 如何轻松查看Oracle的安装版本 Mar 07, 2024 am 11:27 AM

如何轻松查看Oracle的安装版本,需要具体代码示例作为一款被广泛应用于企业级数据库管理系统的软件,Oracle数据库具有许多版本和不同的安装方式。在日常工作中,我们经常需要查看Oracle数据库的安装版本,以便进行相应的操作和维护。本文将介绍如何轻松地查看Oracle的安装版本,并给出具体的代码示例。方法一:通过SQL查询在Oracle数据库中,我们可以通

查看麒麟操作系统版本和内核版本 查看麒麟操作系统版本和内核版本 Feb 21, 2024 pm 07:04 PM

查看麒麟操作系统版本和内核版本在麒麟操作系统中,了解如何查看系统版本和内核版本是进行系统管理和维护的基础。查看麒麟操作系统版本方法一:使用/etc/.kyinfo文件要查看麒麟操作系统的版本,您可以查看/etc/.kyinfo文件。此文件包含了操作系统的版本信息。执行以下命令:cat/etc/.kyinfo此命令将显示操作系统的详细版本信息。方法二:使用/etc/issue文件另一个查看操作系统版本的方法是通过查看/etc/issue文件。这个文件同样提供了版本信息,但可能不如.kyinfo文件

更新pip版本的简单步骤:1分钟内完成 更新pip版本的简单步骤:1分钟内完成 Jan 27, 2024 am 09:45 AM

一分钟搞定:如何更新pip版本,需要具体代码示例随着Python的快速发展,pip成为了Python包管理的标准工具。然而,随着时间的推移,pip版本也在不断更新,为了能够使用最新的功能和修复可能的安全漏洞,更新pip版本是非常重要的。本文将介绍如何在一分钟内快速更新pip,并提供具体的代码示例。首先,我们需要打开命令行窗口。在Windows系统中,可以使用

大模型一对一战斗75万轮,GPT-4夺冠,Llama 3位列第五 大模型一对一战斗75万轮,GPT-4夺冠,Llama 3位列第五 Apr 23, 2024 pm 03:28 PM

关于Llama3,又有测试结果新鲜出炉——大模型评测社区LMSYS发布了一份大模型排行榜单,Llama3位列第五,英文单项与GPT-4并列第一。图片不同于其他Benchmark,这份榜单的依据是模型一对一battle,由全网测评者自行命题并打分。最终,Llama3取得了榜单中的第五名,排在前面的是GPT-4的三个不同版本,以及Claude3超大杯Opus。而在英文单项榜单中,Llama3反超了Claude,与GPT-4打成了平手。对于这一结果,Meta的首席科学家LeCun十分高兴,转发了推文并

dp接口怎么看1.2还是1.4 dp接口怎么看1.2还是1.4 Feb 06, 2024 am 10:27 AM

DP接口是电脑里面一个重要的接口线,有很多用户在使用电脑的时候,想要知道怎么样可以查看DP接口是1.2还是1.4的,其实只需要在GPU-Z中就可以看。dp接口怎么看1.2还是1.4:1、首先在GPU-Z中选择“Advanced”。2、再看“Advanced”下面“General”中的“Monitor1”,可以看“LinkRate(current)”和“Lanes(current)”这两项。3、最后如果显示8.1Gbps×4,就是DP1.3版本以上,一般都是DP1.4,如果是5.4Gbps×4,则

See all articles