file_get_contents receive cookies
Asked Answered
P

7

24

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.

Plop answered 25/11, 2009 at 15:1 Comment(7)
no way to work around this issue?Internuncio
cURL is what you're looking for. But you won't be using file_get_contents(), you'll be using a cURL function. (Note: I linked to the PHP documentation but php.net is currently down, consider googling "php curl" and looking at the cached pages)Marmion
i think cookies are client side, hm? why could file_get_contents get cookies?Anent
You mean you have the cookies of that site , then you want send it to the site , right?Decade
right*. How would I use curl to do this?Internuncio
@Internuncio Just do some search, there are a lot.Decade
@Internuncio there's another way without having to use cURL :)Sugihara
S
25

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.

Sita answered 25/11, 2009 at 15:3 Comment(5)
Is it possible to just store the cookies in a variable, I was trying to prevent writing them to disk. I really just need to pull out one cookie value.Plop
Doesn't look like it. Use php.net/manual/en/function.tempnam.php to create a temp file and remove it after you're done.Plata
@Louis: not with curl but anyway it's kind of a few bytes file and you can just unlink it after you are done.Sita
Reflected in my answer, there are ways to do this (not using CURL) that do not require file storage for cookies.Ouachita
Just a heads up: I tried this but it didn't write the cookie until I added a curl_close($ch) callWystand
C
36

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
Coarse answered 9/6, 2012 at 6:3 Comment(0)
S
25

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.

Sita answered 25/11, 2009 at 15:3 Comment(5)
Is it possible to just store the cookies in a variable, I was trying to prevent writing them to disk. I really just need to pull out one cookie value.Plop
Doesn't look like it. Use php.net/manual/en/function.tempnam.php to create a temp file and remove it after you're done.Plata
@Louis: not with curl but anyway it's kind of a few bytes file and you can just unlink it after you are done.Sita
Reflected in my answer, there are ways to do this (not using CURL) that do not require file storage for cookies.Ouachita
Just a heads up: I tried this but it didn't write the cookie until I added a curl_close($ch) callWystand
D
17

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.

Doyenne answered 9/12, 2010 at 0:51 Comment(3)
Perfect, and the best answer to the original question.Somehow in 12+ years of PHP I'd missed this function.Clarineclarinet
Multiple Set-Cookie lines are captured in $http_response_header; see also a related answer: https://mcmap.net/q/542166/-file_get_contents-receive-cookiesSugihara
I would really be grateful if you could just show us a sample code for those who do NOT "know how to do the whole stream_create_context business to get your file_get_contents http request rolling"Beggary
C
9

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.)
Clarineclarinet answered 17/8, 2011 at 5:22 Comment(1)
Thanks for the follow up. I later discovered this was true, but never did follow up to correct the original answer.Doyenne
C
2

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

Count answered 25/11, 2009 at 15:4 Comment(0)
O
1

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.

Ouachita answered 25/11, 2009 at 15:27 Comment(0)
H
0

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.

Hbeam answered 8/7, 2022 at 13:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.