Come pubblicare dati in PHP usando file_get_contents?


299

Sto usando la funzione di PHP file_get_contents()per recuperare i contenuti di un URL e quindi elaboro le intestazioni attraverso la variabile $http_response_header.

Ora il problema è che alcuni degli URL necessitano di alcuni dati per essere pubblicati nell'URL (ad esempio, le pagine di accesso).

Come lo faccio?

Mi rendo conto che usando stream_context potrei essere in grado di farlo, ma non sono del tutto chiaro.

Grazie.



8
Questo dovrebbe essere votato all'infinito. Non c'è motivo di usare Curl / Guzzle o qualsiasi altra libreria di fantasia se si dispone di funzionalità PHP non elaborate che svolgono il lavoro.
Omar Abid,

Risposte:


589

L'invio di una richiesta POST HTTP utilizzando file_get_contentsnon è così difficile, in realtà: come hai indovinato, devi utilizzare il $contextparametro.


C'è un esempio nel manuale di PHP, in questa pagina: Opzioni di contesto HTTP (citazione) :

$postdata = http_build_query(
    array(
        'var1' => 'some content',
        'var2' => 'doh'
    )
);

$opts = array('http' =>
    array(
        'method'  => 'POST',
        'header'  => 'Content-Type: application/x-www-form-urlencoded',
        'content' => $postdata
    )
);

$context  = stream_context_create($opts);

$result = file_get_contents('http://example.com/submit.php', false, $context);

Fondamentalmente, devi creare uno stream, con le giuste opzioni (c'è un elenco completo in quella pagina) , e usarlo come terzo parametro perfile_get_contents - niente di più ;-)


Come sidenote: in generale, per inviare richieste POST HTTP, tendiamo a usare il ricciolo, che fornisce molte opzioni tutte - ma i flussi sono una delle cose carine di PHP che nessuno conosce ... peccato ... .


1
Grazie. Immagino di poter inserire i contenuti da $ _POST in $ postdata se devo passare gli stessi parametri POST alla pagina richiesta?
Paras Chopra,

6
Suppongo che tu possa fare qualcosa del genere; ma contentnon deve essere un array PHP: deve essere una querystring (ossia deve ha il seguente formato: param1=value1&param2=value2&param3=value3) ;; il che significa che probabilmente dovrai usarehttp_build_query($_POST)
Pascal MARTIN

2
Meraviglioso! Stavo cercando un modo per passare i dati POST a un'altra pagina ottenibile facendo $postdata = http_build_query($_POST).
Liam Newmarch,

1
abbastanza interessante questo non funziona affatto per me l'ho provato per alcune ore e tutti i miei requisiti si trasformano in ottenere
domande

1
Per inviare più valori di intestazione, li gettano in una stringa con \r\ninterruzioni di riga - vedi: stackoverflow.com/a/2107792/404960
rymo

20

In alternativa, puoi anche usare fopen

$params = array('http' => array(
    'method' => 'POST',
    'content' => 'toto=1&tata=2'
));

$ctx = stream_context_create($params);
$fp = @fopen($sUrl, 'rb', false, $ctx);
if (!$fp)
{
    throw new Exception("Problem with $sUrl, $php_errormsg");
}

$response = @stream_get_contents($fp);
if ($response === false) 
{
    throw new Exception("Problem reading data from $sUrl, $php_errormsg");
}

Per qualche motivo, questo ha funzionato per me, ma l'esempio ufficiale di PHP no. +1 anche per toto=1&tata=2. Non ho usato il fopen, tuttavia.
Michael Yaworski,

4
@ Ġiĺàɗ Qui non chiamiamo la gente "noob". Questo è un avvertimento amichevole contro tale.
Dedalo il

0
$sUrl = 'http://www.linktopage.com/login/';
$params = array('http' => array(
    'method'  => 'POST',
    'content' => 'username=admin195&password=d123456789'
));

$ctx = stream_context_create($params);
$fp = @fopen($sUrl, 'rb', false, $ctx);
if(!$fp) {
    throw new Exception("Problem with $sUrl, $php_errormsg");
}

$response = @stream_get_contents($fp);
if($response === false) {
    throw new Exception("Problem reading data from $sUrl, $php_errormsg");
}

2
Prova a fornire una risposta elaborata anziché semplicemente copiare / incollare il codice.
Felipe Leão,

1
Anche questo è inutilmente complicato. Puoi usare file_get_contentsinvece di fopen+ stream_get_contents. E non stai nemmeno chiudendo il "file". Vedi la risposta accettata da @PascalMARTIN.
Martin Prikryl,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.