Вопрос по cookies, php – file_get_contents получить куки

21

Можно ли получить файлы cookie, установленные удаленным сервером при выполненииfile_get_contents запрос?

Мне нужен php для выполнения http-запроса, сохранения файлов cookie, а затем для выполнения второго http-запроса с использованием сохраненных файлов cookie.

cURL это то, что вы ищете. Но вы не будете использоватьfile_get_contents()Вы будете использовать функцию cURL. (Примечание: я ссылался на документацию по PHP, но php.net в настоящее время не работает, подумайте над поиском в Google & php curl & quot; и просматривая кэшированные страницы) jedwards
нет способа обойти эту проблему? Grigor
@ Григор, есть другой способ без использования cURL :) Ja͢ck
@ Григор Просто сделай поиск, там много. xdazz
я думаю, что куки на стороне клиента, а? почему file_get_contents может получить куки? Maziar Aboualizadeh Behbahani

Ваш Ответ

6   ответов
2

Расширение PECL для HTTP, или убедитесь, что ваша установка php была скомпилирована сбиблиотека скручиваемостей.

24

$http_response_header; это массив, содержащий все полученные заголовки. Чтобы извлечь куки, вы должны отфильтровать заголовки, которые начинаются с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);

Эквивалентным, но менее волшебным подходом было бы использование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
6

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

ЗАМЕТКИ:

I'm liberal with the regex; study the RFCs if you want to be more precise (i.e. to reject badly formed cookie data) 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. 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.)
Спасибо за продолжение. Позже я обнаружил, что это было правдой, но так и не исправил первоначальный ответ.
21

cURL для этой цели,cURL реализовать функцию, называемую jar cookie, которая позволяет сохранять куки в файле и повторно использовать их для последующего запроса (запросов).

Вот краткий фрагмент кода, как это сделать:

/* 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: следует отметить, что у вас должно быть установлено расширение pecl (или скомпилировано в PHP), иначе у вас не будет доступа к API cURL.

Просто наперед: я пробовал это, но он не записывал cookie, пока не добавил вызов curl_close ($ ch)
Можно ли просто сохранить куки в переменной, я пытался предотвратить их запись на диск. Мне просто нужно вытащить одно значение cookie. Louis W
Отраженный в моем ответе, есть способы сделать это (не используя CURL), которые не требуют хранения файлов для куки.
@Louis: не с curl, но в любом случае это файл в несколько байтов, и вы можете простоunlink это после того, как вы сделали.
Не похоже на это. использованиеphp.net/manual/en/function.tempnam.php создать временный файл и удалить его после того, как вы закончите.
1

что вы можете сделать это довольно легко с объектом Zend_Http. Вот документация одобавление куки на запрос.

Чтобы получить куки-файлы из запроса (я полагаю, что он получен автоматически), просто используйтеgetCookieJar() на объекте Zend_Http.

Это должно быть легко осуществить; однако в руководстве пользователя php есть комментарий пользователякак бороться с куки, используя поток http.

14

что это поздно, но на самом деле есть способ, по крайней мере, получать отдельные куки, отправленные сервером.

Я предполагаю, что вы знаете, как сделать весь бизнес stream_create_context, чтобы получить ваш http-запрос file_get_contents, и вам просто нужна помощь в настройке файлов cookie.

После запуска file_get_contents по URL-адресу устанавливается (к сожалению, неассоциативный) массив $ http_response_header.

Если сервер отправляет обратно cookie, один из них будет начинаться с «Set-Cookie:», который можно извлечь с помощью substr.

Однако в данный момент мне кажется, что через эту переменную можно получить доступ только к -one-Set-Cookie, что является ограничением, которое я сейчас пытаюсь найти способ обойти.

Идеальный и лучший ответ на оригинальный вопрос. Как-то за 12 с лишним лет PHP я пропустил эту функцию.
множественныйSet-Cookie линии захвачены в$http_response_header; см. также связанный ответ:stackoverflow.com/a/10958820/1338292
Я был бы очень признателен, если бы вы могли просто показать нам пример кода для тех, кто НЕ"know how to do the whole stream_create_context business to get your file_get_contents http request rolling"

Похожие вопросы