Php Curl send File AND array data Php Curl send File AND array data curl curl

Php Curl send File AND array data


After very long research to manage the same problem, I think that a simpler solution could be:

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

this is the right way to emulate what happen on browsers

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

The result is:

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


After long research and testing i`ve got the (not very nice 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: addition 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;    }