2009-11-25 17 views
19

¿Es posible recibir las cookies establecidas por el servidor remoto al hacer una solicitud file_get_contents?file_get_contents recibir cookies

Necesito php para hacer una solicitud http, almacenar las cookies, y luego hacer una segunda solicitud http utilizando las cookies almacenadas.

+0

hay manera de evitar este problema? – Grigor

+0

[cURL] (http://php.net/manual/en/book.curl.php) es lo que estás buscando. Pero no usará 'file_get_contents()', usará una función cURL. (Nota: he vinculado a la documentación de PHP, pero php.net está actualmente fuera de servicio, considere buscar en Google "php curl" y mirar las páginas almacenadas en caché) – jedwards

+0

Creo que las cookies son del lado del cliente, ¿verdad? ¿Por qué podría file_get_contents obtener cookies? –

Respuesta

18

debe usar cURL para tal fin, cURL implementar una característica llamada cookie jar que permite guardar cookies en un archivo y reutilizarlas para solicitudes posteriores.

Aquí vienen un código rápido snipet cómo hacerlo:

/* STEP 1. let’s create a cookie file */ 
$ckfile = tempnam ("/tmp", "CURLCOOKIE"); 
/* STEP 2. visit the homepage to set the cookie properly */ 
$ch = curl_init ("http://somedomain.com/"); 
curl_setopt ($ch, CURLOPT_COOKIEJAR, $ckfile); 
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true); 
$output = curl_exec ($ch); 

/* STEP 3. visit cookiepage.php */ 
$ch = curl_init ("http://somedomain.com/cookiepage.php"); 
curl_setopt ($ch, CURLOPT_COOKIEFILE, $ckfile); 
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true); 
$output = curl_exec ($ch); 

nota: se ha de señalar que debe tener la extensión PECL (o compilada en PHP) instalados o que no tendrá acceso a la API cURL.

+0

¿Es posible simplemente almacenar las cookies en una variable, estaba tratando de evitar escribirlas en el disco. Realmente solo necesito sacar un valor de cookie. –

+0

No se ve así. Use http://www.php.net/manual/en/function.tempnam.php para crear un archivo temporal y eliminarlo una vez que haya terminado. – ceejayoz

+0

@Louis: no con curl, pero de todos modos es como un archivo de pocos bytes y puedes 'desvincularlo 'cuando hayas terminado. – RageZ

1

Creo que puede hacerlo bastante fácilmente con el objeto Zend_Http. Aquí está la documentación sobre adding cookies a una solicitud.

Para obtener las cookies de una solicitud (automáticamente recuperada, creo), simplemente use getCookieJar() en el objeto Zend_Http.

Debe ser fácil de implementar; sin embargo, el manual php tiene un comentario del usuario en how to deal with cookies using the http stream.

13

Me doy cuenta de esto es, tarde, pero en realidad hay una manera de al menos recibir las cookies individuales enviadas por el servidor.

Supongo que sabe cómo hacer todo el negocio de stream_create_context para que su solicitud http file_get_contents funcione, y solo necesita ayuda para configurar las cookies.

Después de ejecutar file_get_contents en una url, se establece la matriz (desafortunadamente, no asociativa) $ http_response_header.

Si el servidor devuelve una cookie, una de ellas comenzará con 'Set-Cookie:', que puede extraer con substr.

Sin embargo, por el momento, me parece que uno solo puede acceder a una-Set-Cookie a través de esta variable, que es una limitación que estoy tratando de encontrar una forma de evitar.

+0

Perfecto, y la mejor respuesta a la pregunta original. De alguna manera en más de 12 años de PHP me había perdido esta función. –

+0

Se capturan varias líneas 'Set-Cookie' en' $ http_response_header'; vea también una respuesta relacionada: http://stackoverflow.com/a/10958820/1338292 –

+0

Realmente le agradecería si pudiera mostrarnos un código de muestra para aquellos que NO "saben cómo hacer todo el negocio de stream_create_context para Obtenga su solicitud HTTP file_get_contents rolling "' – azerafati

6

A raíz de la respuesta de Laereom, aquí es cómo conseguir varias cookies:

$cookies=array(); 
foreach($http_response_header as $s){ 
    if(preg_match('|^Set-Cookie:\s*([^=]+)=([^;]+);(.+)$|',$s,$parts)) 
     $cookies[$parts[1]]=$parts[2]; 
    } 

NOTAS:

  1. soy liberal con la expresión regular; estudie los RFC si quiere ser más preciso (es decir, para rechazar datos de cookies mal formados)
  2. Encontrará path =, expires =, etc. en $ parts [3]. Sugeriría explode(';',$parts[3]) y luego otro ciclo para procesarlo (porque no estoy seguro de si hay un orden fijo para estos atributos.
  3. Si dos cookies tienen la misma parte de nombre, solo la última sobrevive, lo que parece ser correcto .(Me sucede que tiene esta situación en mi proyecto actual;. Asumo que es un error en la página web Estoy pantalla-raspado)
+0

Gracias por el seguimiento. Más tarde descubrí que esto era cierto, pero nunca hice un seguimiento para corregir la respuesta original. – Laereom

21

Hay una variable mágica para esto, llamado $http_response_header; es una matriz que comprende todos los encabezados que se recibieron. Para extraer las cookies, debe filtrar los encabezados que comienzan con Set-Cookie:.

file_get_contents('http://example.org'); 

$cookies = array(); 
foreach ($http_response_header as $hdr) { 
    if (preg_match('/^Set-Cookie:\s*([^;]+)/', $hdr, $matches)) { 
     parse_str($matches[1], $tmp); 
     $cookies += $tmp; 
    } 
} 
print_r($cookies); 

un enfoque equivalente pero menos mágico sería utilizar stream_get_meta_data():

if (false !== ($f = fopen('http://www.example.org', 'r'))) { 
     $meta = stream_get_meta_data($f); 
     $headers = $meta['wrapper_data']; 

     $contents = stream_get_contents($f); 
     fclose($f); 
} 
// $headers now contains the same array as $http_response_header 
+0

@GaryCarlyleCook depende de lo que quiera hacer; no tenía la intención de tratar de obtener contenidos, sino más de demostrar la obtención de datos de cookies –