Php simulates post requests to send files. Php simulates post requests to send files because of project requirements, the local server needs to receive data and then forward the data to another server. Therefore, it needs to simulate post requests to send data, php simulates post requests to send files
Because of project requirements, the local server needs to receive data and then forward the data to another server. Therefore, it is necessary to use a post request to send data. of course, the data also contains file streams.
Curl is one of the common php methods. the general code is as follows:
$ Params1 = test; $ params2 = @. $ absolute_path; // if it is a file, the parameter is @ + absolute path $ post_data = array ('params1 '=> $ params1, 'params2' => $ params2 ,); function postData ($ url, $ data) {$ ch = curl_init (); $ timeout = 300; curl_setopt ($ ch, CURLOPT_URL, $ url ); // request address // curl_setopt ($ ch, CURLOPT_REFERER, $ ip); // Construct curl_setopt ($ ch, CURLOPT_POST, true); // post request curl_setopt ($ ch, CURLOPT_BINARYTRANSFER, true); // binary stream curl_setopt ($ ch, CURLOPT_POSTFIELDS, $ data); // data curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, 1 ); // when CURLOPT_RETURNTRANSFER is set to 1, $ head has the returned value curl_setopt ($ ch, CURLOPT_CONNECTTIMEOUT, $ timeout); // sets the request timeout Time $ handles = curl_exec ($ ch ); curl_close ($ ch); return $ handles ;}
The other party is a java Server. I only know the interface and I don't know how the other party processes the received files. The above method is successful in the Windows wamp environment, but the code fails to be put on the centOS + Nginx server, and the returned message is an error in receiving the file. After packet capture analysis, we found that the formats of the packages delivered by Windows 7 wamp are different from those of the http packages delivered by centos nginx. In general, curl sets content_type to multipart/form-data by default. this is true under win7 wamp on my machine, however, in centos nginx, it is application/x-www-form-urlencoded. Of course, this may also be a problem with server configuration, but I don't know where the problem is. Then I checked the PHP version, which is PHP5.3.X but slightly different. It is not ruled out that the PHP version is a problem. Then add the code:
$header = array('Content-Type: multipart/form-data',);curl_setopt( $ch, CURLOPT_HTTPHEADER, $header);
Set the header, but it is still invalid in centos. The content-type cannot be changed.
Later, with the help of the technical director, I saw a link on the official PHP website http://php.net/manual/en/class.curlfile.php. I used the official website to complete the post request in win wamp and centos nginx. After carefully reading the code, I found that the entire http request body was written, instead of the curl self-generated part, and I had to admire it. The following code is released:
function postData($url, $data = array(), $data1 = array()){ $header = array('Content-Type: multipart/form-data',);$ch = curl_init(); curl_setopt ($ch, CURLOPT_URL, $url);curl_setopt( $ch, CURLOPT_HTTPHEADER, $header);curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT,10);curl_setopt ($ch, CURLOPT_BINARYTRANSFER,true); //curl_setopt ($ch, CURLOPT_POSTFIELDS, $data);curl_custom_postfields($ch, $data, $data1);$dxycontent = curl_exec($ch);curl_close($ch);return $dxycontent;}/*** For safe multipart POST request for PHP5.3 ~ PHP 5.4.* * @param resource $ch cURL resource* @param array $assoc name => value* @param array $files name => path* @return bool*/function curl_custom_postfields($ch, array $assoc = array(), array $files = array()) {// invalid characters for name and filenamestatic $disallow = array(, , , );// build normal parametersforeach ($assoc as $k => $v) {$k = str_replace($disallow, _, $k);$body[] = implode(, array(Content-Disposition: form-data; name={$k},,filter_var($v), ));}// build file parametersforeach ($files as $k => $v) {switch (true) {case false === $v = realpath(filter_var($v)):case !is_file($v):case !is_readable($v):continue; // or return false, throw new InvalidArgumentException}$data = file_get_contents($v);$v = call_user_func(end, explode(DIRECTORY_SEPARATOR, $v));$k = str_replace($disallow, _, $k);$v = str_replace($disallow, _, $v);$body[] = implode(, array(Content-Disposition: form-data; name={$k}; filename={$v},Content-Type: application/octet-stream,,$data, ));}// generate safe boundary do {$boundary = --------------------- . md5(mt_rand() . microtime());} while (preg_grep(/{$boundary}/, $body));// add boundary for each parametersarray_walk($body, function (&$part) use ($boundary) {$part = --{$boundary}{$part};});// add final boundary$body[] = --{$boundary}--;$body[] = ;// set optionsreturn @curl_setopt_array($ch, array(CURLOPT_POST => true,CURLOPT_POSTFIELDS => implode(, $body),CURLOPT_HTTPHEADER => array(Expect: 100-continue,Content-Type: multipart/form-data; boundary={$boundary}, // change Content-Type),));}
Parameter transfer is not affected. if the file is an absolute path, + @. The only difference is that the file data and common data are distinguished by different arrays, and different processing is performed when simulating the http body part. Finally, the file is successfully uploaded.
Because of the project requirements, the local server needs to receive data and then forward the data to another server. Therefore, it is necessary to use a post request to send data ,...