Curl POST-формат для CURLOPT_POSTFIELDS

Когда я использую curl через POST и устанавливаю CURLOPT_POSTFIELD, мне нужно urlencode или какой-либо специальный формат?

например: Если я хочу опубликовать 2 поля, первый и последний:

first=John&last=Smith

каков точный код/​​формат, который должен использоваться с curl?

$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$reply=curl_exec($ch);
curl_close($ch);

Ответ 1

Если вы отправляете строку, urlencode() это. В противном случае, если массив, он должен иметь значение key = > , а заголовок Content-type автоматически устанавливается на multipart/form-data.

Кроме того, вам не нужно создавать дополнительные функции для построения запроса для ваших массивов, вы уже имеете это:

$query = http_build_query($data, '', '&');

Ответ 2

EDIT: от php5 вверх рекомендуется использовать http_build_query:

string http_build_query ( mixed $query_data [, string $numeric_prefix [, 
                          string $arg_separator [, int $enc_type = PHP_QUERY_RFC1738 ]]] )

Простой пример из руководства:

<?php
$data = array('foo'=>'bar',
              'baz'=>'boom',
              'cow'=>'milk',
              'php'=>'hypertext processor');

echo http_build_query($data) . "\n";

/* output:
foo=bar&baz=boom&cow=milk&php=hypertext+processor
*/

?>

до php5:

Из manual:

CURLOPT_POSTFIELDS

Полные данные для публикации в HTTP-режиме "POST". Чтобы опубликовать файл, добавьте имя файла с помощью @и используйте полный путь. Тип файла может быть явно указан, следуя имени файла с типом в формате '; type = mimetype'. Этот параметр может быть передан как строка с urlencoded, как 'para1 = val1 & para2 = val2 &...' или как массив с именем поля в качестве ключа и данными поля в качестве значения. Если значением является массив, заголовок Content-Type будет установлен в multipart/form-data. Как и в случае с PHP 5.2.0, файлы, переданные этому параметру с префиксом @, должны быть в форме массива для работы.

Итак, что-то вроде этого должно работать отлично (с параметрами, переданными в ассоциативном массиве):

function preparePostFields($array) {
  $params = array();

  foreach ($array as $key => $value) {
    $params[] = $key . '=' . urlencode($value);
  }

  return implode('&', $params);
}

Ответ 3

Не передавать строку вообще!

Вы можете передать массив и позволить php/curl выполнять грязную работу с кодировкой и т.д.

Ответ 4

В соответствии с руководством PHP данные, переданные cURL в виде строки, должны быть скопированы URL. Смотрите curl_setopt() и выполните поиск CURLOPT_POSTFIELDS.

Ответ 5

Для CURLOPT_POSTFIELDS параметры могут быть переданы как строка с urlencoded, например para1=val1&para2=val2&.., или как массив с именем поля в качестве ключа и данными поля как значение

Попробуйте следующий формат:

$data = json_encode(array(
"first"  => "John",
"last" => "Smith"
));

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$output = curl_exec($ch);
curl_close($ch);

Ответ 6

Этот ответ взял меня навсегда, чтобы найти. Я обнаружил, что все, что вам нужно сделать, это конкатенация URL-адреса ( "?" После имени файла и расширения) с помощью строки запроса с кодировкой URL. Это даже не похоже на то, что вы должны установить параметры POST cURL. См. Поддельный пример ниже:

//create URL
$exampleURL = 'http://www.example.com/example.php?';

// create curl resource
$ch = curl_init(); 

// build URL-encoded query string
$data = http_build_query(
    array('first' => 'John', 'last' => 'Smith', '&'); // set url
curl_setopt($ch, CURLOPT_URL, $exampleURL . $data); 

// return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

// $output contains the output string
$output = curl_exec($ch); 

// close curl resource to free up system resources <br/>
curl_close($ch);

Вы также можете использовать file_get_contents():

// read entire webpage file into a string
$output = file_get_contents($exampleURL . $data);