Analysis of curl upload file version difference problem

小云云
Release: 2023-03-20 18:16:01
Original
1504 people have browsed it

=After the front-end post form uploads the file, after the back-end receives the file, it forwards the post to the image server. So I used curl to upload and uploaded using '@file path'

The code is as follows

<?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);

   }
Copy after login
Copy after login

The PHP version of the test machine is 5.2. There is no problem in breaking the code, but putting it on the line Above, the $_FILES variable cannot receive a value. Then observe carefully, I received $_POST['video']='@/tmp/phps12d63'; in $_POST. This is quite strange. The first reaction is that the Content-Type is not transmitted normally, and the Content-Type of the uploaded file should be It is 'multipart/form-data', in this case it should be 'application/x-www-form-urlencoded'. Then print the $_SERVER[‘HTTP_CONTENT_TYPE’] variable on the image server and find that it is ‘multipart/form-data’.
Checking the manual, I found that if the passed parameter of CURLOPT_POSTFIELDS is an array, the Content-Type header will be set to multipart/form-data.
Then there is also a magical CURLOPT_SAFE_UPLOAD parameter, added in php5.5.0, the default value is false, 5.6.0 defaults to true,

CURLOPT_SAFE_UPLOAD
TRUE disables sending files with the @ prefix in CURLOPT_POSTFIELDS. This means @ can be safely used in fields. be usable
CURLFile as a replacement for uploading.

And CURLOPT_POSTFIELDS parameter description

CURLOPT_POSTFIELDS
All data is sent using the "POST" operation in the HTTP protocol. To send a file, prefix the file name with @ and use the full path. The file type can be specified in the format ‘;type=mimetype’ after the file name. This parameter can be a urlencoded string, similar to 'para1=val1¶2=val2&...', or you can use an array with the field name as the key and the field data as the value. If value is an array, the Content-Type header will be set to multipart/form-data. Starting from PHP 5.2.0, when passing files using the @ prefix, value must be an array. Starting with PHP 5.5.0, the @ prefix has been deprecated and files can be sent via CURLFile. Set CURLOPT_SAFE_UPLOAD to TRUE to disable sending files with the @ prefix for added security.

Looking at the version, it turns out that the test environment is php5.3, and the online test environment is 5.6, which means that CURLOPT_SAFE_UPLOAD defaults to true, @ upload is disabled, and @ is an ordinary string. Starting from 5.5, the @ prefix for uploading files has been abandoned. Versions greater than 5.5 need to be uploaded using CURLFile. The final compatible solution uses the @ prefix if it is less than 5.5, and CURLFile if it is greater than 5.5. For versions less than 5.5, use @ to upload and you can add additional parameters; filename = file name; type = mime type

<?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" : '');
    }
}
Copy after login
Copy after login

The final code is

<?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);

   }
Copy after login
Copy after login

In conclusion, when encountering a problem, you should analyze it calmly first, and then read the manual carefully.

I encountered a problem on Friday. After the front-end post form uploads a file, after the back-end receives the file, it forwards the post to the image server. So I used curl to upload and uploaded using '@file path'
The code is as follows

<?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);

   }
Copy after login
Copy after login

The PHP version of the test machine is 5.2. There is no problem in breaking the code, but when it is put online, the $_FILES variable is dead or alive. No value received. Then observe carefully, I received $_POST['video']='@/tmp/phps12d63'; in $_POST. This is quite strange. The first reaction is that the Content-Type is not transmitted normally, and the Content-Type of the uploaded file should be It is 'multipart/form-data', in this case it should be 'application/x-www-form-urlencoded'. Then print the $_SERVER[‘HTTP_CONTENT_TYPE’] variable on the image server and find that it is ‘multipart/form-data’.
Check the manual and found that if the passed parameter of CURLOPT_POSTFIELDS is an array, the Content-Type header will be set to multipart/form-data.
Then there is also a magical CURLOPT_SAFE_UPLOAD parameter, added in php5.5.0, the default value is false, 5.6.0 defaults to true,

CURLOPT_SAFE_UPLOAD
TRUE disables sending files with the @ prefix in CURLOPT_POSTFIELDS. This means @ can be safely used in fields. be usable
CURLFile as a replacement for uploading.

And CURLOPT_POSTFIELDS parameter description

CURLOPT_POSTFIELDS
All data is sent using the "POST" operation in the HTTP protocol. To send a file, prefix the file name with @ and use the full path. The file type can be specified in the format ‘;type=mimetype’ after the file name. This parameter can be a urlencoded string, similar to 'para1=val1¶2=val2&...', or you can use an array with the field name as the key and the field data as the value. If value is an array, the Content-Type header will be set to multipart/form-data. Starting from PHP 5.2.0, when passing files using the @ prefix, value must be an array. Starting with PHP 5.5.0, the @ prefix has been deprecated and files can be sent via CURLFile. Set CURLOPT_SAFE_UPLOAD to TRUE to disable sending files with the @ prefix for added security.

查看版本,果然测试环境是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" : '');
    }
}
Copy after login
Copy after login

最后代码为

<?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);

   }
Copy after login
Copy after login

相关推荐:

php通过CURL上传文件

php curl上传文件的简单例子

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

The above is the detailed content of Analysis of curl upload file version difference problem. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!