¿Cómo publicar datos en PHP usando file_get_contents?


299

Estoy usando la función de PHP file_get_contents()para recuperar el contenido de una URL y luego procesar encabezados a través de la variable $http_response_header.

Ahora el problema es que algunas de las URL necesitan algunos datos para publicarse en la URL (por ejemplo, páginas de inicio de sesión).

¿Cómo puedo hacer eso?

Me doy cuenta de que usando stream_context puedo hacerlo, pero no estoy del todo claro.

Gracias.



8
Esto debería ser votado infinitamente. No hay ninguna razón para usar Curl / Guzzle o cualquier otra biblioteca sofisticada si tiene una funcionalidad PHP en bruto que hace el trabajo.
Omar Abid

Respuestas:


589

Enviar una solicitud HTTP POST usando file_get_contentsno es tan difícil, en realidad: como adivinó, debe usar el $contextparámetro.


Hay un ejemplo dado en el manual de PHP, en esta página: Opciones de contexto HTTP (cita) :

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

Básicamente, debe crear una secuencia, con las opciones correctas (hay una lista completa en esa página) , y usarla como el tercer parámetro para file_get_contents- nada más ;-)


Como nota al margen: en términos generales, para enviar solicitudes HTTP POST, tendemos a usar curl, que ofrece muchas opciones y todo, pero las transmisiones son una de las cosas buenas de PHP que nadie sabe ... demasiado mal ... .


1
Gracias. Supongo que puedo insertar el contenido de $ _POST en $ postdata si necesito pasar los mismos parámetros POST a la página solicitada.
Paras Chopra

66
Supongo que puedes hacer algo así; pero contentno debe ser una matriz PHP: tiene que ser una cadena de consulta (es decir, debe tiene este formato: param1=value1&param2=value2&param3=value3) ;; Lo que significa que probablemente tendrá que usarhttp_build_query($_POST)
Pascal MARTIN

2
¡Maravilloso! Estaba buscando una manera de pasar los datos POST a otra página que se puede lograr haciendo $postdata = http_build_query($_POST).
Liam Newmarch

1
lo suficientemente interesante, esto no funciona para mí en absoluto, lo he intentado durante unas horas y todas mis solicitudes se convierten en consultas de consulta
WojonsTech

1
Para enviar múltiples valores de encabezado, tírelos a todos en una cadena con \r\nsaltos de línea; consulte: stackoverflow.com/a/2107792/404960
rymo

20

Una alternativa, también puedes usar 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");
}

Por alguna razón, esto funcionó para mí, pero el ejemplo oficial de PHP no. +1 para el toto=1&tata=2también. No utilicé el fopen, sin embargo.
Michael Yaworski

44
@ Ġiĺàɗ Aquí no llamamos a la gente 'novato'. Esta es una advertencia amistosa contra tal.
Dédalo

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
Por favor, intente proporcionar una respuesta elaborada en lugar de simplemente copiar / pegar el código.
Felipe Leão

1
Además, esto es innecesariamente complicado. Puedes usar en file_get_contentslugar de fopen+ stream_get_contents. Y ni siquiera está cerrando el "archivo". Vea la respuesta aceptada por @PascalMARTIN.
Martin Prikryl
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.