13 Stimmen

Mischen mehrerer Werte für denselben Schlüssel und Datei-Uploads mit cURL und PHP

Ich bin auf eine Einschränkung in den cURL-Bindings für PHP gestoßen. Es scheint, dass es keine einfache Möglichkeit gibt, mehrere Werte für denselben Schlüssel für Postfields zu senden. Die meisten Workarounds, auf die ich gestoßen bin, bestanden darin, die URL-kodierten Postfelder von Hand zu erstellen (tag=foo&tag=bar&tag=baz), anstatt die assoziative Array-Version von CURLOPT_POSTFIELDS zu verwenden.

Es scheint, wie eine ziemlich gemeinsame Sache zu müssen, um zu unterstützen, so dass ich das Gefühl, ich muss etwas verpasst haben. Ist dies wirklich der einzige Weg, um mehrere Werte für den gleichen Schlüssel zu behandeln?

Während diese Problemumgehung als praktikabel (wenn auch nicht wirklich ärgerlich) angesehen werden könnte, ist mein Hauptproblem, dass ich in der Lage sein muss, mehrere Werte für den gleichen Schlüssel zu tun und auch Datei-Upload unterstützen. Soweit ich sagen kann, Dateiupload mehr oder weniger erfordert, um die assoziierte arravy Version von CURLOPT_POSTFIELDS zu verwenden. Ich fühle mich also wie ich bin stecken.

Ich habe gepostet Ich habe dieses Problem auf der cURL-PHP-Mailingliste ausführlicher beschrieben, in der Hoffnung, dass dort jemand eine Idee dazu hat.

Für Vorschläge oder Hinweise, wo ich weitere Informationen zu diesem Thema finden kann, bin ich sehr dankbar!

12voto

Beau Simensen Punkte 4498

Ich habe schließlich meine eigene Funktion geschrieben, um eine benutzerdefinierte CURLOPT_POSTFIELDS-Zeichenfolge mit multipart/form-data zu erstellen. Was für eine Qual.

function curl_setopt_custom_postfields($ch, $postfields, $headers = null) {
    // $postfields is an assoc array.
    // Creates a boundary.
    // Reads each postfields, detects which are @files, and which values are arrays
    // and dumps them into a new array (not an assoc array) so each key can exist
    // multiple times.
    // Sets content-length, content-type and sets CURLOPT_POSTFIELDS with the
    // generated body.
}

Ich konnte diese Methode wie folgt anwenden:

curl_setopt_custom_postfields($ch, array(
    'file' => '@/path/to/file',
    'tag' => array('a', 'b', 'c'),
));

Ich bin mir der CURLOPT_HTTPHEADER-Stapel nicht sicher. Da diese Methode sie aufruft, habe ich dafür gesorgt, dass die Funktion es dem Benutzer ermöglicht, bei Bedarf zusätzliche Header anzugeben.

Ich habe den vollständigen Code verfügbar in diesem Blogeintrag .

0 Stimmen

Ich glaube, das beantwortet meine Frage, aber ich sehe keine Möglichkeit, meine Frage wirklich zu "beantworten" :) Bitte bewerten Sie das hoch, damit vielleicht eines Tages jemand es für mich akzeptieren kann oder so?

0 Stimmen

Sie können ab sofort Ihre eigenen Antworten akzeptieren, siehe blog.stackoverflow.com/2009/01/accept-your-own-answers

0 Stimmen

Überrascht niemand sonst hat jemals über diese gekommen, scheint wie etwas, das Teil der cURL-Php-Bibliothek sein sollte! Danke, dass Sie mein Leben einfacher machen!

3voto

Paul Dixon Punkte 286600

Wenn Sie tag[] statt tag für den Namen, PHP erzeugt ein Array für Sie, mit anderen Worten, anstatt

tag=foo&tag=bar&tag=baz

Sie benötigen

tag[]=foo&tag[]=bar&tag[]=baz

Beachten Sie, dass dies, wenn es für die Übertragung urlencodiert wird, zu

tag%5B%5D=foo&tag%5B%5D=bar&tag%5B%5D=baz

0 Stimmen

Ich weiß, wie man Arrays in Formularen und URLs erstellt, die PHP lesen kann. Das Problem ist, dass ich auf einer Nicht-PHP-Seite poste, die den []-Hack nicht verwendet. Selbst wenn dies der Fall wäre, wird cURL nicht 'tag[]' => array('a', 'b', 'c') akzeptieren und die Anfrage so erstellen, wie Sie es vorschlagen. Das ist das Problem.

3voto

Jehong Ahn Punkte 1022
  1. Stimmen Sie für PHP Fehler #51634 .
  2. Versuchen Sie die Antwort von @BeauSimensen.
  3. Guzzle kann dies tun. Siehe ein Beispiel unten.

    $client = new \GuzzleHttp\Client(); $client->request('POST', $url, [ 'multipart' => [ [ 'name' => 'foo', 'contents' => 'bar' ], [ 'name' => 'foo', 'contents' => 'baz' ], ] ]);

2voto

Sandro Punkte 61

Ich habe es zum Laufen gebracht:

curl_setopt($ch, CURLOPT_POSTFIELDS,array('tag[0]'=>'val0','tag[1]'=>'val1'));

entonces $_POST führt zu: $_POST['tag'][0] = 'val0' y $_POST['tag'][1] = 'val1'

2voto

berg Punkte 580

Ich bin auf das gleiche Problem gestoßen. Aber ich konnte es auf diese Weise lösen.

for($cnt = 0; $cnt < count($siteRows); $cnt++)
{
    $curlParams['site_ids['.$cnt.']'] = $siteRows[$cnt]->site_id; 
}

Funktioniert auch für Dateien:

for($cnt = 0; $cnt < count($imageRows); $cnt++)
{
    $curlParams['product_images['.$cnt.']'] = '@'.$imageRows[$cnt]->full_path;
}

0 Stimmen

Nutzt die php-spezifische Interpretation von Post-Feldnamen, so funktioniert nur, wenn Ihr Ziel läuft php, aber da dies eine Frage über das Schreiben der Client-Seite in php ist, nehme ich an, dass wahrscheinlich ist. Es hat mir geholfen, +1

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X