Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

file_get_contents receive cookies

Tags:

php

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.

like image 947
Louis W Avatar asked Nov 25 '09 15:11

Louis W


People also ask

What will the file_get_contents () return?

The function returns the read data or false on failure. This function may return Boolean false , but may also return a non-Boolean value which evaluates to false .

Is file_get_contents secure?

file_get_contents in itself appears safe, as it retrieves the URL and places it into a string. As long as you're not processing the string in any script engine or using is as any execution parameter you should be safe.

Does file_get_contents cache?

Short answer: No. file_get_contents is basically just a shortcut for fopen, fread, fclose etc - so I imagine opening a file pointer and freading it isn't cached.

What is the function file_get_contents () useful for?

The file_get_contents() reads a file into a string. This function is the preferred way to read the contents of a file into a string.


4 Answers

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
like image 194
Ja͢ck Avatar answered Oct 09 '22 20:10

Ja͢ck


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.

like image 39
RageZ Avatar answered Oct 09 '22 21:10

RageZ


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.

like image 17
Laereom Avatar answered Oct 09 '22 21:10

Laereom


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.)
like image 9
Darren Cook Avatar answered Oct 09 '22 22:10

Darren Cook