curl POST формат для CURLOPT_POSTFIELDS - PullRequest
95 голосов
/ 07 марта 2011

Когда я использую 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);

Ответы [ 9 ]

94 голосов
/ 07 марта 2011

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

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

$query = http_build_query($data, '', '&');
56 голосов
/ 07 марта 2011

РЕДАКТИРОВАТЬ : начиная с 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:

Из руководства :

CURLOPT_POSTFIELDS

Полные данные для отправки в HTTP-операции «POST». Чтобы опубликовать файл, добавьте @ к имени файла и используйте полный путь. Тип файла можно явно указать, следуя имени файла с типом в формате '; type = mimetype'. Этот параметр может быть передан в виде строки в кодировке urlen, например '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);
}
37 голосов
/ 07 марта 2011

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

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

3 голосов
/ 05 июля 2018

Еще одно существенное отличие, которое здесь еще не упомянуто, заключается в том, что CURLOPT_POSTFIELDS не может обрабатывать вложенные массивы.

Если мы возьмем вложенный массив ['a' => 1, 'b' => [2, 3, 4]], то это должно быть параметризовано как a=1&b[]=2&b[]=3&b[]=4 ([ и ] будут / должны быть закодированы в URL). Это будет автоматически преобразовано обратно во вложенный массив на другом конце (при условии, что здесь другой конец также является PHP).

Это будет работать:

var_dump(http_build_query(['a' => 1, 'b' => [2, 3, 4]]));
// output: string(36) "a=1&b%5B0%5D=2&b%5B1%5D=3&b%5B2%5D=4"

Это не сработает:

curl_setopt($ch, CURLOPT_POSTFIELDS, ['a' => 1, 'b' => [2, 3, 4]]);

Это даст вам уведомление. Выполнение кода будет продолжено, и ваша конечная точка получит параметр b в виде строки "Array":

Примечание PHP: преобразование массива в строку в ... on line ...

3 голосов
/ 07 марта 2011

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

2 голосов
/ 27 июля 2018

для вложенных массивов вы можете использовать:

$data = [
  'name[0]' = 'value 1',
  'name[1]' = 'value 2',
  'name[2]' = 'value 3',
  'id' = 'value 4',
  ....
];
0 голосов
/ 07 февраля 2019

Интересно, что Почтальон делает POST полной операцией GET с этими 2 дополнительными опциями:

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, '');

Просто другой способ, и он работает очень хорошо.

0 голосов
/ 10 марта 2016

Для CURLOPT_POSTFIELDS параметры могут быть переданы в виде строки с кодировкой urlen-кода, например 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);
0 голосов
/ 23 июня 2013

Этот ответ занял у меня тоже много времени.Я обнаружил, что все, что вам нужно сделать, это объединить 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...