804 Stimmen

Wie sende ich eine POST-Anfrage mit PHP?

Eigentlich möchte ich die Inhalte lesen, die nach der Suchanfrage kommen, wenn diese abgeschlossen ist. Das Problem ist, dass die URL nur POST Methoden, und es werden keine Maßnahmen mit GET Methode...

Ich muss alle Inhalte mit Hilfe von domdocument o file_get_contents() . Gibt es eine Methode, mit der ich Parameter mit POST Methode und lesen Sie dann den Inhalt über PHP ?

1459voto

dbau Punkte 15509

CURL-loses Verfahren mit PHP5:

$url = 'http://server.com/path';
$data = array('key1' => 'value1', 'key2' => 'value2');

// use key 'http' even if you send the request to https://...
$options = array(
    'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'method'  => 'POST',
        'content' => http_build_query($data)
    )
);
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { /* Handle error */ }

var_dump($result);

Im PHP-Handbuch finden Sie weitere Informationen über die Methode und wie Sie z.B. Header hinzufügen können:

74 Stimmen

Wenn Sie sich entscheiden, ein Array für die Header zu verwenden, sollten Sie die Schlüssel oder Werte NICHT mit ' \r\n '. stream_context_create() nimmt den Text nur bis zur ersten ' \r\n '

14 Stimmen

Eine URL kann als Dateiname verwendet werden mit file_get_contents() nur, wenn die fopen-Wrapper aktiviert wurden. Siehe php.net/manual/de/

2 Stimmen

Ich habe dies versucht, aber ich habe den gesamten Inhalt der Datei zurückbekommen :(

195voto

Fred Tanrikut Punkte 9571

Sie könnten verwenden cURL :

<?php
//The url you wish to send the POST request to
$url = $file_name;

//The data you want to send via POST
$fields = [
    '__VIEWSTATE '      => $state,
    '__EVENTVALIDATION' => $valid,
    'btnSubmit'         => 'Submit'
];

//url-ify the data for the POST
$fields_string = http_build_query($fields);

//open connection
$ch = curl_init();

//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);

//So that curl_exec returns the contents of the cURL; rather than echoing it
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true); 

//execute post
$result = curl_exec($ch);
echo $result;
?>

4 Stimmen

Dies funktionierte für mich, weil die Seite, die ich an eine Seite, die keinen Inhalt hat, so dass die file_get_contents Version nicht funktionieren.

11 Stimmen

Die file_get_contents-Lösung funktioniert nicht bei PHP-Konfigurationen mit allow_url_fopen Off (wie bei Shared Hosting). Diese Version verwendet die curl-Bibliothek und ist meiner Meinung nach am "universellsten", daher gebe ich Ihnen meine Stimme

115 Stimmen

Sie haben nicht angegeben, woher Sie dieses Codebeispiel kopiert haben: davidwalsh.name/curl-post

88voto

Dima L. Punkte 3143

Ich verwende die folgende Funktion, um Daten mit curl zu posten. $data ist ein Array von Feldern, die gepostet werden sollen (sie werden mit http_build_query korrekt kodiert). Die Daten werden mit application/x-www-form-urlencoded kodiert.

function httpPost($url, $data)
{
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($curl);
    curl_close($curl);
    return $response;
}

@Edward erwähnt, dass http_build_query weggelassen werden kann, da curl das an den Parameter CURLOPT_POSTFIELDS übergebene Array korrekt kodieren wird.

Ich verwende diese Funktion bei APIs, die erwarten, dass die Daten mit application/x-www-form-urlencoded kodiert werden. Aus diesem Grund verwende ich http_build_query().

0 Stimmen

Die Übergabe eines Arrays an CURLOPT_POSTFIELDS führt dazu, dass die Daten mit multipart/form-data kodiert werden, was möglicherweise nicht erwünscht ist.

0 Stimmen

Der Benutzer hat nach file_get_contents gefragt, also braucht er eine Lösung, um den default_stream_context zu ändern

0 Stimmen

Zur Klarstellung: Ich glaube, @DimaL. antwortet auf einen Kommentar, der gelöscht wurde; http_build_query konvertiert $data Array in eine Zeichenkette umwandeln, um eine Ausgabe als multipart/form-data zu vermeiden.

53voto

Andreas Punkte 2701

Ich empfehle Ihnen, das Open-Source-Paket guzzle die vollständig einheitlich getestet ist und die neuesten Codierungsverfahren verwendet.

Installieren von Guzzle

Gehen Sie zur Befehlszeile in Ihrem Projektordner und geben Sie den folgenden Befehl ein (vorausgesetzt, Sie haben bereits den Paketmanager Komponist installiert). Wenn Sie Hilfe bei der Installation von Composer benötigen, Hier sollten Sie nachsehen .

php composer.phar require guzzlehttp/guzzle

Verwendung von Guzzle zum Senden einer POST-Anfrage

Die Verwendung von Guzzle ist sehr einfach, da es eine leichtgewichtige objektorientierte API verwendet:

// Initialize Guzzle client
$client = new GuzzleHttp\Client();

// Create a POST request
$response = $client->request(
    'POST',
    'http://example.org/',
    [
        'form_params' => [
            'key1' => 'value1',
            'key2' => 'value2'
        ]
    ]
);

// Parse the response object, e.g. read the headers, body, etc.
$headers = $response->getHeaders();
$body = $response->getBody();

// Output headers and body for debugging purposes
var_dump($headers, $body);

10 Stimmen

Es wäre nützlich zu wissen, welche Vorteile dies gegenüber der bereits geposteten nativen PHP-Lösung und auch der cURL-Lösung hat.

13 Stimmen

@artfulrobot: Die native PHP-Lösung hat eine Menge Probleme (z.B. Verbindung mit https, Zertifikatsüberprüfung, etc.pp.), weshalb fast jeder PHP-Entwickler cURL verwendet. Und warum sollte man in diesem Fall nicht cURL verwenden? Das ist ganz einfach: Guzzle hat eine unkomplizierte, einfache und leichtgewichtige Schnittstelle, die all diese "Low-Level cURL-Handling-Probleme" ausblendet. Fast jeder, der modernes PHP entwickelt, verwendet ohnehin Composer, so dass die Verwendung von Guzzle wirklich einfach ist.

2 Stimmen

Danke, ich weiß, dass Guzzle populär ist, aber es gibt Anwendungsfälle, in denen Composer Kummer bereitet (z.B. bei der Entwicklung von Plugins für größere Software-Projekte, die bereits eine (andere Version) von Guzzle oder andere Abhängigkeiten verwenden), daher ist es gut, diese Informationen zu kennen, um eine Entscheidung darüber zu treffen, welche Lösung am robustesten ist

33voto

mwatzer Punkte 806

Ich möchte einige Gedanken zu der auf Curl basierenden Antwort von Fred Tanrikut hinzufügen. Ich weiß, dass die meisten davon bereits in den obigen Antworten enthalten sind, aber ich denke, es ist eine gute Idee, eine Antwort zu zeigen, die alle zusammen enthält.

Hier ist die Klasse, die ich geschrieben habe, um HTTP-GET/POST/PUT/DELETE-Anfragen auf der Basis von curl zu stellen, die nur den Antwortkörper betreffen:

class HTTPRequester {
    /**
     * @description Make HTTP-GET call
     * @param       $url
     * @param       array $params
     * @return      HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPGet($url, array $params) {
        $query = http_build_query($params); 
        $ch    = curl_init($url.'?'.$query);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }
    /**
     * @description Make HTTP-POST call
     * @param       $url
     * @param       array $params
     * @return      HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPPost($url, array $params) {
        $query = http_build_query($params);
        $ch    = curl_init();
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }
    /**
     * @description Make HTTP-PUT call
     * @param       $url
     * @param       array $params
     * @return      HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPPut($url, array $params) {
        $query = \http_build_query($params);
        $ch    = \curl_init();
        \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
        \curl_setopt($ch, \CURLOPT_HEADER, false);
        \curl_setopt($ch, \CURLOPT_URL, $url);
        \curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'PUT');
        \curl_setopt($ch, \CURLOPT_POSTFIELDS, $query);
        $response = \curl_exec($ch);
        \curl_close($ch);
        return $response;
    }
    /**
     * @category Make HTTP-DELETE call
     * @param    $url
     * @param    array $params
     * @return   HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPDelete($url, array $params) {
        $query = \http_build_query($params);
        $ch    = \curl_init();
        \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
        \curl_setopt($ch, \CURLOPT_HEADER, false);
        \curl_setopt($ch, \CURLOPT_URL, $url);
        \curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'DELETE');
        \curl_setopt($ch, \CURLOPT_POSTFIELDS, $query);
        $response = \curl_exec($ch);
        \curl_close($ch);
        return $response;
    }
}

Verbesserungen

  • Verwendung von http_build_query, um den Query-String aus einem Request-Array zu erhalten. (Sie könnten auch das Array selbst verwenden, siehe dazu: http://php.net/manual/en/function.curl-setopt.php )
  • Rückgabe der Antwort anstelle eines Echos. Übrigens können Sie die Rückgabe vermeiden, indem Sie die Zeile curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); . Danach ist der Rückgabewert ein boolescher Wert (true = Anfrage war erfolgreich, sonst ist ein Fehler aufgetreten) und die Antwort wird als Echo ausgegeben. Siehe: http://php.net/en/manual/function.curl-exec.php
  • Sauberes Schließen der Sitzung und Löschen des Curl-Handlers durch Verwendung von curl_close . Siehe: http://php.net/manual/en/function.curl-close.php
  • Die Verwendung boolescher Werte für die curl_setopt (Ich weiß, dass jede Zahl ungleich Null auch als wahr angesehen wird, aber die Verwendung von wahr erzeugt einen besser lesbaren Code, aber das ist nur meine Meinung)
  • Fähigkeit, HTTP-PUT/DELETE-Aufrufe zu tätigen (nützlich für das Testen von RESTful-Diensten)

Beispiel für die Verwendung

GET

$response = HTTPRequester::HTTPGet("http://localhost/service/foobar.php", array("getParam" => "foobar"));

POST

$response = HTTPRequester::HTTPPost("http://localhost/service/foobar.php", array("postParam" => "foobar"));

PUT

$response = HTTPRequester::HTTPPut("http://localhost/service/foobar.php", array("putParam" => "foobar"));

DELETE

$response = HTTPRequester::HTTPDelete("http://localhost/service/foobar.php", array("deleteParam" => "foobar"));

Prüfung

Mit dieser einfachen Klasse können Sie auch einige coole Diensttests durchführen.

class HTTPRequesterCase extends TestCase {
    /**
     * @description test static method HTTPGet
     */
    public function testHTTPGet() {
        $requestArr = array("getLicenses" => 1);
        $url        = "http://localhost/project/req/licenseService.php";
        $this->assertEquals(HTTPRequester::HTTPGet($url, $requestArr), '[{"error":false,"val":["NONE","AGPL","GPLv3"]}]');
    }
    /**
     * @description test static method HTTPPost
     */
    public function testHTTPPost() {
        $requestArr = array("addPerson" => array("foo", "bar"));
        $url        = "http://localhost/project/req/personService.php";
        $this->assertEquals(HTTPRequester::HTTPPost($url, $requestArr), '[{"error":false}]');
    }
    /**
     * @description test static method HTTPPut
     */
    public function testHTTPPut() {
        $requestArr = array("updatePerson" => array("foo", "bar"));
        $url        = "http://localhost/project/req/personService.php";
        $this->assertEquals(HTTPRequester::HTTPPut($url, $requestArr), '[{"error":false}]');
    }
    /**
     * @description test static method HTTPDelete
     */
    public function testHTTPDelete() {
        $requestArr = array("deletePerson" => array("foo", "bar"));
        $url        = "http://localhost/project/req/personService.php";
        $this->assertEquals(HTTPRequester::HTTPDelete($url, $requestArr), '[{"error":false}]');
    }
}

1 Stimmen

Für mich heißt es "Unerwarteter Fehler: Aufruf einer undefinierten Methode HTTPRequester::HTTPost()" . Ich habe Ihre Klasse einfach in meine .php-Datei eingefügt. Muss ich noch irgendetwas anderes tun?

1 Stimmen

Können Sie bitte Ihren Code veröffentlichen? Es ist ziemlich schwer zu erraten, was falsch ist, ohne ein Code-Snippet.

1 Stimmen

Wie ich schon sagte, habe ich buchstäblich Ihre in meine einfache php-Datei kopiert, und es gab mir diesen Fehler.

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