Lorsque j'utilise curl
via POST
et que je définis CURLOPT_POSTFIELD
, dois-je urlencode
ou un format spécial?
par exemple: Si je veux poster 2 champs, premier et dernier:
first=John&last=Smith
quel est le code/format exact à utiliser avec 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);
Si vous envoyez une chaîne, urlencode () la. Sinon, si array, il devrait s'agir d'une clé => valeur associée et l'en-tête Content-type
est automatiquement défini sur multipart/form-data
.
De plus, vous n'avez pas besoin de créer des fonctions supplémentaires pour construire la requête pour vos tableaux, vous avez déjà cela:
$query = http_build_query($data, '', '&');
EDIT: à partir de php5, l'utilisation de http_build_query
est recommandée:
string http_build_query ( mixed $query_data [, string $numeric_prefix [,
string $arg_separator [, int $enc_type = PHP_QUERY_RFC1738 ]]] )
Exemple simple tiré du manuel:
<?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
*/
?>
avant php5:
De la manuel :
CURLOPT_POSTFIELDS
Les données complètes à publier dans une opération HTTP "POST". Pour poster un fichier, ajoutez un @ à un nom de fichier et utilisez le chemin complet. Le type de fichier peut être spécifié explicitement en suivant le nom du fichier avec le type au format '; type = type MIME'. Ce paramètre peut être passé sous forme de chaîne codée par url, telle que 'para1 = val1 & para2 = val2 & ...' ou sous forme de tableau avec le nom du champ comme clé et les données du champ comme valeur. Si value est un tableau, l'en-tête Content-Type sera défini sur multipart/form-data. À partir de PHP 5.2.0, les fichiers transmis à cette option avec le préfixe @ doivent être sous forme de tableau pour fonctionner.
Donc, quelque chose comme ceci devrait fonctionner parfaitement (avec les paramètres passés dans un tableau associatif):
function preparePostFields($array) {
$params = array();
foreach ($array as $key => $value) {
$params[] = $key . '=' . urlencode($value);
}
return implode('&', $params);
}
Vous pouvez passer un tableau et laisser php/curl faire le sale travail d’encodage, etc.
Selon le manuel PHP, les données transmises à cURL sous forme de chaîne doivent être encodées en URL. Voir la page pour curl_setopt () et recherchez CURLOPT_POSTFIELDS
.
Une autre différence majeure qui n’a pas encore été mentionnée ici est que CURLOPT_POSTFIELDS
ne peut pas gérer les tableaux imbriqués.
Si nous prenons le tableau imbriqué ['a' => 1, 'b' => [2, 3, 4]]
, il devrait être paramétré comme a=1&b[]=2&b[]=3&b[]=4
(le [
et le ]
seront/devraient être codés en URL) Ceci sera reconverti automatiquement en un tableau imbriqué à l'autre extrémité (en supposant qu'ici l'autre extrémité est aussi PHP).
Cela fonctionnera:
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"
Cela ne fonctionnera pas:
curl_setopt($ch, CURLOPT_POSTFIELDS, ['a' => 1, 'b' => [2, 3, 4]]);
Cela vous donnera un avis. L'exécution du code se poursuivra et votre noeud final recevra le paramètre b
sous la forme de la chaîne "Array"
:
Avis PHP: Conversion de tableau en chaînes dans ... en ligne ...
pour les tableaux imbriqués, vous pouvez utiliser:
$data = [
'name[0]' = 'value 1',
'name[1]' = 'value 2',
'name[2]' = 'value 3',
'id' = 'value 4',
....
];
Pour CURLOPT_POSTFIELDS
, les paramètres peuvent être transmis sous forme de chaîne codée par l'url telle que para1=val1¶2=val2&..
ou sous forme de tableau avec le nom du champ comme clé et les données du champ comme valeur.
Essayez le format suivant:
$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);
Il est intéressant de noter que la manière Postman do POST est une opération GET complète avec ces 2 options supplémentaires:
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, '');
Juste une autre manière, et cela fonctionne très bien.