Louis W
Louis W

Reputation: 3262

file_get_contents receive cookies

Is it possible to receive the cookies set by the remote server when doing a file_get_contents request?

I need php to do a http request, store the cookies, and then make a second http request using the stored cookies.

Upvotes: 25

Views: 31087

Answers (7)

Tomás Cot
Tomás Cot

Reputation: 1013

There's a shorter option using preg_grep:

$cookiesArray = preg_grep('/^Set-Cookie/i', $http_response_header);

This is gonna return an array with the Set-Cookie headers, then you'll have to get the cookie from each header, as the cookie header can include the path and some other flags.

Upvotes: 1

Ja͢ck
Ja͢ck

Reputation: 173642

There's a magic variable for this, called $http_response_header; it's an array comprising all headers that were received. To extract the cookies you have to filter out the headers that start with 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);

An equivalent but less magical approach would be to use 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

Upvotes: 36

Darren Cook
Darren Cook

Reputation: 28938

Following on from Laereom's answer, here is how to get multiple cookies:

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

NOTES:

  1. I'm liberal with the regex; study the RFCs if you want to be more precise (i.e. to reject badly formed cookie data)
  2. You'll find path=, expires=, etc. in $parts[3]. I'd suggest explode(';',$parts[3]) then another loop to process it (because I'm not sure if there is a fixed order for these attributes.
  3. If two cookies have the same name part, only the last survives, which appears to be correct. (I happen to have this situation in my current project; I assume it is a bug in the website I'm screen-scraping.)

Upvotes: 9

Laereom
Laereom

Reputation: 621

I realize this is, late, but there is actually a way to at least receive individual cookies sent by the server.

I'm assuming you know how to do the whole stream_create_context business to get your file_get_contents http request rolling, and you just need assistance actually setting the cookies.

After running file_get_contents on a url, the (unfortunately, non-associative) array $http_response_header is set.

If the server is sending back a cookie, one of them will start with 'Set-Cookie: ', which you can extract with substr.

However, at the moment, it appears to me that one can only access -one- Set-Cookie through this variable, which is a limitation I am currently trying to find a way to work around.

Upvotes: 17

RageZ
RageZ

Reputation: 27323

you should use cURL for that purpose, cURL implement a feature called the cookie jar which permit to save cookies in a file and reuse them for subsequent request(s).

Here come a quick code snipet how to do it:

/* 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);

note: has to be noted you should have the pecl extension (or compiled in PHP) installed or you won't have access to the cURL API.

Upvotes: 26

Tim Lytle
Tim Lytle

Reputation: 17624

I believe you co do it pretty easily with the Zend_Http object. Here is the documentation about adding cookies to a request.

To get the cookies from a request (automatically retrieved I believe), just use getCookieJar() on the Zend_Http object.

That should be easy to implement; however, the php manual has a user comment on how to deal with cookies using the http stream.

Upvotes: 1

soulmerge
soulmerge

Reputation: 75724

You can either install and use the PECL extension for HTTP, or make sure your php installation was compiled with the optional curl library.

Upvotes: 2

Related Questions