2016-03-01 13 views
6

Chcę wysłać złożone dane pocztowe z Curl.Php Curl wysyła dane zbioru i tablicy

Dane próbuję wysłać:

Array 
(
    [test] => Array 
     (
      [0] => 1 
      [1] => 2 
      [2] => 3 
     ) 

    [file] => CURLFile Object 
     (
      [name] => H:\wwwroot\curl/upload.txt 
      [mime] => 
      [postname] => 
     ) 

) 

muszę używać zmiennych w post-side jak $ _POST [ "test"] i $ _FILES [ "plik"] ale nie mogę uświadom to sobie. Dla (czasem wielowymiarowych) danych tablicowych potrzebuję http_build_query, ale to powoduje uszkodzenie pliku. Jeśli nie korzystam z http_build_query, moja tablica daje błąd "array to string conversion".

Jak mogę to uruchomić? Kod:

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); 
+0

Najpierw należy zakodować dane pliku Base64. http://php.net/manual/en/function.base64-encode.php – jjwdesign

Odpowiedz

2

Po długich badaniach i testach `ve got (niezbyt ładne, ale działa) rozwiązanie:

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; 
} 

Badanie za pomocą:

$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: dodanie funkcji addPostData:

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; 
    } 
+0

co robi 'addPostData'? – silenzium

+0

Przepraszamy! Sprawdź mój zredagowany wpis –

2

Po bardzo długich badaniach zarządzać ten sam problem, myślę, że prostszym rozwiązaniem mogłoby być:

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

to Właściwy sposób naśladowania tego, co dzieje się w przeglądarkach:

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

Rezultat:

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 
     ) 

)