Curl-POST-Format für CURLOPT_POSTFIELDS

99

Wenn ich curlüber POSTund Satz zu CURLOPT_POSTFIELDtun habe ich urlencodeoder irgendein spezielles Format?

Zum Beispiel: Wenn ich 2 Felder posten möchte, zuerst und zuletzt:

first=John&last=Smith

Was ist der genaue Code / das genaue Format, das mit Curl verwendet werden soll?

$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);
Ken
quelle

Antworten:

100

Wenn Sie eine Zeichenfolge senden, geben Sie urlencode () ein. Andernfalls sollte bei Array Schlüssel => Wert gepaart sein und der Content-typeHeader wird automatisch auf gesetzt multipart/form-data.

Außerdem müssen Sie keine zusätzlichen Funktionen erstellen, um die Abfrage für Ihre Arrays zu erstellen. Sie haben bereits Folgendes:

$query = http_build_query($data, '', '&');
Kodeart
quelle
13
Sie können nur verwenden, http_build_query($data)da dies &das Standardtrennzeichen ist.
Nichtigkeit
6
Natürlich können Sie sie überspringen. Dies soll die beiden anderen Argumente veranschaulichen, die Sie ändern können (oder auch nicht) (z. B. das Standardtrennzeichen), um Ihren spezifischen Anforderungen zu entsprechen.
Kodeart
62

EDIT : Ab PHP5 wird die Verwendung von http_build_queryempfohlen:

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

Einfaches Beispiel aus dem Handbuch:

<?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
*/

?>

vor php5:

Aus dem Handbuch :

CURLOPT_POSTFIELDS

Die vollständigen Daten, die in einem HTTP-POST-Vorgang veröffentlicht werden sollen. Um eine Datei zu veröffentlichen, stellen Sie einen Dateinamen mit @ voran und verwenden Sie den vollständigen Pfad. Der Dateityp kann explizit angegeben werden, indem dem Dateinamen der Typ im Format '; type = mimetype' gefolgt wird. Dieser Parameter kann entweder als urlencodierter String wie 'para1 = val1 & para2 = val2 & ...' oder als Array mit dem Feldnamen als Schlüssel und den Felddaten als Wert übergeben werden. Wenn value ein Array ist, wird der Content-Type-Header auf multipart / form-data gesetzt. Ab PHP 5.2.0 müssen Dateien, die mit dem Präfix @ an diese Option übergeben werden, in Array-Form vorliegen, damit sie funktionieren.

So etwas sollte also perfekt funktionieren (mit Parametern, die in einem assoziativen Array übergeben werden):

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

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

  return implode('&', $params);
}
Tschechologie
quelle
11
Warum würden Sie eine Zeichenfolge übergeben, wenn Sie ein Array übergeben können ...?
ThiefMaster
1
Ich denke, $ key sollte auch codiert werden, nur für den Fall, dass Sie es wie "Name & Nachname" usw. haben. Besonders wenn Daten vom Endbenutzer angegeben werden
Marius Balčytis
2
@barius, ich stimme dir zu. Und ich denke, http_build_query () ist tatsächlich besser als die oben definierte Funktion.
Himmelfrei
1
@skyfree Ich stimme zu! Diese Funktion wurde in PHP5 hinzugefügt, was 2011 noch weit vom Standard entfernt war.
Czechnology
1
Warum ist http_build_query erforderlich, wenn Sie nur ein Array übergeben können?
Offenso
39

Übergeben Sie überhaupt keine Schnur!

Sie können ein Array übergeben und PHP / Curl die schmutzige Arbeit der Codierung usw. erledigen lassen.

DiebMaster
quelle
16
Das Übergeben eines Arrays hat einen anderen Inhaltstyp als eine Zeichenfolge. Es gibt also einen guten Grund, dies zu tun. Ich habe eine Weile gebraucht, um das herauszufinden.
Thomas Vander Stichele
Ich habe keine Ahnung warum, aber ich finde, dass auf meinem Win Dev PC das Übergeben eines Arrays etwa eine Sekunde länger dauert (1,029 Sekunden mit Array gegenüber 0,016 Sekunden mit http_build_query()demselben Array)
kratenko
2
Verschachtelte Arrays funktionieren nicht. cURL wird versuchen, sie in einen String zu konvertieren, und ein Hinweis zur Konvertierung von PHP- Arrays in einen String wird folgen
7ochem
5

Laut PHP-Handbuch sollten Daten, die als Zeichenfolge an cURL übergeben werden, URL-codiert sein. Siehe die Seite für curl_setopt () und suchen Sie nach CURLOPT_POSTFIELDS.

Surreale Träume
quelle
4

Denn CURLOPT_POSTFIELDSdie Parameter können entweder als urlencodierte Zeichenfolge para1=val1&para2=val2&..oder als Array mit dem Feldnamen als Schlüssel und den Felddaten als Wert übergeben werden

Versuchen Sie das folgende Format:

$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);
Shraddha Vadnere
quelle
2
Hallo Shraddha, json_encode()ich gebe dir etwas ganz anderes als eine gültige Parameterzeichenfolge als first=John&last=Smith. json_encode()wird ausgegeben: {"first":"John","last":"Smith"}Dies wird dann der Rohkörper Ihrer POST-Anfrage.
7ochem
1
So fügen Sie dem Kommentar von @ 7ochem hinzu: Es sei denn, der Empfänger erwartet einen einzelnen Parameter, der eine json-codierte Zeichenfolge enthält , anstatt json_encode(...)do http_build_query(...). Dadurch wird die erwartete "URL-codierte Zeichenfolge" erstellt, die die durch "&" getrennten Parameter enthält.
ToolmakerSteve
4

Ein weiterer wichtiger Unterschied, der hier noch nicht erwähnt wird, besteht darin, dass CURLOPT_POSTFIELDSverschachtelte Arrays nicht verarbeitet werden können.

Wenn wir das verschachtelte Array verwenden, ['a' => 1, 'b' => [2, 3, 4]]sollte dies als parametrisiert werden a=1&b[]=2&b[]=3&b[]=4(das [und ]wird / sollte URL-codiert sein). Dies wird am anderen Ende automatisch wieder in ein verschachteltes Array konvertiert (vorausgesetzt, das andere Ende ist ebenfalls PHP).

Das wird funktionieren:

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"

Das wird nicht funktionieren:

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

Dies wird Sie benachrichtigen. Die Codeausführung wird fortgesetzt und Ihr Endpunkt erhält den Parameter bals Zeichenfolge "Array":

PHP Hinweis: Konvertierung von Array in String in ... online ...

7ochem
quelle
4

Es kommt auf die an content-type

URL-codierte oder mehrteilige / Formulardaten

Um Daten auf die übliche Weise zu senden, wie es ein Browser mit einem Formular tun würde, übergeben Sie einfach ein assoziatives Array . Wie im PHP-Handbuch angegeben:

Dieser Parameter kann entweder als urlencodierter String wie 'para1 = val1 & para2 = val2 & ...' oder als Array mit dem Feldnamen als Schlüssel und den Felddaten als Wert übergeben werden. Wenn value ein Array ist, wird der Content-Type-Header auf multipart / form-data gesetzt.

JSON-Codierung

Bei der Kommunikation mit JSON-APIs muss der Inhalt jedoch JSON-codiert sein, damit die API unsere POST-Daten versteht.

In solchen Fällen muss der Inhalt explizit als JSON codiert werden:

CURLOPT_POSTFIELDS => json_encode(['param1' => $param1, 'param2' => $param2]),

Bei der Kommunikation in JSON setzen acceptund content-typekopieren wir normalerweise auch entsprechend:

CURLOPT_HTTPHEADER => [
    'accept: application/json',
    'content-type: application/json'
]
Buzut
quelle
2

Für verschachtelte Arrays können Sie Folgendes verwenden:

$data = [
  'name[0]' = 'value 1',
  'name[1]' = 'value 2',
  'name[2]' = 'value 3',
  'id' = 'value 4',
  ....
];
Maxim Rysevets
quelle
0

Interessanterweise ist die Art und Weise, wie Postman POST ausführt, eine vollständige GET-Operation mit diesen zwei zusätzlichen Optionen:

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

Nur ein anderer Weg, und es funktioniert sehr gut.

Klompenrunner
quelle
-3

Diese Antwort hat mich ewig gekostet. Ich habe festgestellt, dass Sie lediglich die URL ('?' Nach dem Dateinamen und der Erweiterung) mit der URL-codierten Abfragezeichenfolge verketten müssen. Es sieht nicht einmal so aus, als müssten Sie die POST cURL-Optionen festlegen. Siehe das gefälschte Beispiel unten:

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

Sie können auch verwenden file_get_contents():

// read entire webpage file into a string
$output = file_get_contents($exampleURL . $data);
user2512571
quelle
9
Es scheint, als ob Sie eher ein GET als ein POST durchführen.
Großmutter