Differences between different PHP versions of cURL (-experience)

Source: Internet
Author: User
The difference between different versions of PHP cURL (-experience) is a collection tool before, to achieve the collected articles, pictures are saved. the content of the article is stored in the database, and the image needs to be uploaded to the image server first, and then the image address is returned, replacing the image address of the article.

The problem is that everything can be collected successfully. However, local testing is normal and images can be uploaded successfully, but there is no image in the production environment. then I debug it step by step and find that all the data is available, but why did I fail to upload images in production.

After a few days, I finally found the answer after reading the code, debugging, and Baidu step by step.

The uploaded image server uses curl post,

PHP cURL supports generating POST requests for multipart/form-data by passing an associated array (instead of a string) to CURL_POSTFIELDS.

Traditionally, PHP cURL supports appending a file in the array data using the "@ + file full path" syntax for cURL to read and upload. This is consistent with the syntax for directly calling the cURL program through the command line:

curl_setopt(ch, CURLOPT_POSTFIELDS, array( 'file' => '@'.realpath('image.png'),));equals$ curl -F "file=@/absolute/path/to/image.png" 
 

However, PHP introduced a new CURLFile class from 5.5 to point to a file. The CURLFile class can also define the MIME type, file name, and other additional information that may appear in multipart/form-data. In PHP, we recommend that you use CURLFile to replace the old @ syntax:

curl_setopt(ch, CURLOPT_POSTFIELDS, [    'file' => new CURLFile(realpath('image.png')),]);

PHP 5.5 also introduces the CURL_SAFE_UPLOAD option, which forces the PHP cURL module to reject the old @ syntax and only accept files in the CURLFile format. The default value of 5.5 is false, and the default value of 5.6 is true.

However, the pitfall is: @ syntax has been deprecated in 5.5, and is deleted directly in 5.6 (ErorException will occur: the usage of the @ filename API for file uploading is deprecated. please use the CURLFile class instead ).

For PHP 5.6 +, manually set CURL_SAFE_UPLOAD to falseMeaningless. It is not literally understood as "set to false, you can enable the old unsafe method"-the old method is no longer used as an obsolete syntax. PHP 5.6 + = CURLFile only, do not have any fantasies.

My deployment environment is 5.4 (only @ syntax), but the development environment is 5.6 (only CURLFile ). Neither version 5.5 nor supports the transitional version. The result is that two sets of code with environment judgment must be written.

Now the problem is ......

Environment judgment: be careful with magic numbers!

I have seen code for this environment judgment:

if (version_compare(phpversion(), '5.4.0') >= 0)

I have only one word for this code:Shit.

This judgment falls into a typicalMagic number trap. The version number appears inexplicably in the code. without checking the PHP manual and update history for half a day, it is difficult to understand which function The author is stuck in.

The code should return to the source. Our actual requirement is: the use of CURLFile is preferred without degrading to the traditional @ syntax. Then the code comes:

if (class_exists('\CURLFile')) { $field = array('fieldname' => new \CURLFile(realpath($filepath)));} else { $field = array('fieldname' => '@' . realpath($filepath));}
We recommend that you specify degradation options explicitly.

From a reliable perspective, we recommend that you specify the value of CURL_SAFE_UPLOAD to explicitly tell php whether to tolerate or disable the old @ syntax. Note that in earlier PHP versions, the CURLOPT_SAFE_UPLOAD constant may not exist. you need to determine the following:

if (class_exists('\CURLFile')) { curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true);} else { if (defined('CURLOPT_SAFE_UPLOAD')) { curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false); }}
CURL option setting order

No matter whether curl_setopt () is single-shot or curl_setopt_array (), the cURL option is always set to take effect, and the set option immediately affects the behavior of cURL when setting subsequent options.

For example, CURLOPT_SAFE_UPLOAD is related to the behavior of CURLOPT_POSTFIELDS. If you first set CURLOPT_POSTFIELDS and then set CURLOPT_SAFE_UPLOAD, the latter's constraint will not take effect. Because when the former is set, the cURL has completed the actual read and write of the data!

There are several options in cURL, so be careful. Fortunately, there are not many options for "dependency", and the mechanism is not complex. you can simply process them. My method is to set all the options in batches first, and then set CURLOPT_POSTFIELDS only one time before curl_exec.

In fact, the array used by curl_setopt_array () ensures that the location of CURLOPT_POSTFIELDS is reliable.PHP's associated arrays are ordered.We can also assume that the execution sequence inside curl_setopt_array () must be from start to end in order [note A], so you can rest assured.

My practice is to add extra insurance to the code performance, highlighting the importance of order to prevent future attacks.

Namespace

PHP 5.2 or earlier versions have no namespace. When space separator \ is used in the code, a parser error is thrown. Taking care of PHP 5.2 is actually easy to think about, just give up the namespace.

Note that PHP 5.3 + has a namespace. Whether you call CURLFile or use class_exists () to determine the existence of CURLFile, we recommend that you write \ CURLFile to specify the top-level space to prevent code packages from collapsing in the namespace.

All right, this trap is dug deep. just jump out and share it.

(The above solution is to repost the website. thank you for letting me find your article !)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.