Php Curl sends file and array data

I want to send complex Post data using Curl.

The data I'm trying to send:

Array ( [test] => Array ( [0] => 1 [1] => 2 [2] => 3 ) [file] => CURLFile Object ( [name] => H:\wwwroot\curl/upload.txt [mime] => [postname] => ) ) 

I need to use variables in the post-side like $ _POST ["test"] and $ _FILES ["file"] But I can't figure it out. For (sometimes multidimensional) datasets, I need http_build_query, but that breaks the file. If I do not use http_build_query, my array gives the error "convert array to string".

How can I make this work? Code:

Index.php

 $curl = curl_init(); $postValues = Array("test" => Array(1,2,3)); $postValues["file"] = new CurlFile(dirname(__FILE__). "/upload.txt"); curl_setopt($curl, CURLOPT_URL, "localhost/curl/post.php"); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $postValues); curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); $curlResult = curl_exec($curl); $curlStatus = curl_getinfo($curl); echo $curlResult; 

post.php

 print_r($_REQUEST); print_r($_FILES); 
+6
source share
2 answers

After much research and testing, I got a (not very pleasant, but working) solution:

 function createHttpHeader($postValues, $overrideKey = null) { global $delimiter; // invalid characters for "name" and "filename" $disallow = array("\0", "\"", "\r", "\n"); $data = Array(); if (!is_array($postValues)) { $postValues = Array($postValues); } foreach($postValues as $key => $value) { $useKey = $overrideKey === null ? $key : $overrideKey. "[$key]"; $useKey = str_replace($disallow, "_", $useKey); if (is_array($value)) { $data = array_merge($data, addPostData($value, $useKey)); } else { $data[] = "--". $delimiter. "\r\n"; $data[] = "Content-Disposition: form-data; name=\"". $useKey. "\""; if (is_a($value, "\CurlFile")) { $data[] = "; filename=\"". basename($value->name). "\"\r\n"; $data[] = "Content-Type: application/octet-stream\r\n\r\n"; $data[] = file_get_contents($value->name). "\r\n"; } else { $data[] = "\r\n\r\n". $value. "\r\n"; } } } return $data; } 

Test with

 $postValues = Array( "blaat" => 1, "test" => Array(1,2,3), "grid" => Array(0 => array(1,2), 1 => array(4,5)), "gridComplex" => Array("rows" => array(1,2), "columns" => array(0 => array(1,2,3,4), 1 => array(4,5,4,5))) ); $postValues["file[0]"] = new CurlFile($file, "text/plain"); $postValues["file[1]"] = new CurlFile($file, "text/plain"); // print_r(new CurlFile($file));exit; $delimiter = "-------------" . uniqid(); $data = createHttpHeader($postValues); $data[] = "--" . $delimiter . "--\r\n"; $data = implode("", $data); $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, "localhost/curl/post.php"); curl_setopt($curl, CURLOPT_HTTPHEADER , array('Content-Type: multipart/form-data; boundary=' . $delimiter, 'Content-Length: ' . strlen($data))); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $data); curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); $curlResult = curl_exec($curl); echo $curlResult; 

Edit: adding the addPostData function:

  function addPostData($postValues, $delimiter, $overrideKey = null) { // invalid characters for "name" and "filename" $disallow = array("\0", "\"", "\r", "\n"); $data = Array(); if (!is_array($postValues)) { $postValues = Array($postValues); } foreach($postValues as $key => $value) { $useKey = $overrideKey === null ? $key : $overrideKey. "[$key]"; $useKey = str_replace($disallow, "_", $useKey); if (is_array($value)) { $data = array_merge($data, $this->addPostData($value, $delimiter, $useKey)); } else { $data[] = "--". $delimiter. "\r\n"; $data[] = "Content-Disposition: form-data; name=\"". $useKey. "\""; if (is_a($value, "\CurlFile")) { $data[] = "; filename=\"". basename($value->postname). "\"\r\n"; $data[] = "Content-Type: ". $value->mime. "\r\n\r\n"; $data[] = file_get_contents($value->name). "\r\n"; } else { $data[] = "\r\n\r\n". $value. "\r\n"; } } } return $data; } 
+2
source

After very lengthy research to solve the same problem, I think a simpler solution could be:

$postValues = Array("test[0]" => 1, "test[1]" => 2, "test[2]" => 3);

this is the right way to emulate what happens in browsers

 <input type="hidden" name="test[0]" value="1"> <input type="hidden" name="test[1]" value="2"> ... 

Result:

 Array ( [test] => Array ( [0] => 1 [1] => 2 [2] => 3 ) ) Array ( [file] => Array ( [name] => upload.txt [type] => application/octet-stream [tmp_name] => /tmp/phprRGsPU [error] => 0 [size] => 30 ) ) 
+2
source

All Articles