how to get the cookies from a php curl into a variable
因此,其他公司的一些人认为,如果不使用soap或xml-rpc或rest或任何其他合理的通信协议,而只是将其所有响应作为cookie嵌入到标头中,那将是很棒的。
我需要从这些curl响应中将这些cookie作为一个数组拉出。 如果我不得不花大量时间为此编写解析器,我将非常不高兴。
有谁知道如何简单地做到这一点,最好不要在文件中写入任何内容?
如果有人可以帮助我,我将非常感激。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $ch = curl_init('http://www.google.com/'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // get headers too with this line curl_setopt($ch, CURLOPT_HEADER, 1); $result = curl_exec($ch); // get cookie // multi-cookie variant contributed by @Combuster in comments preg_match_all('/^Set-Cookie:\\s*([^;]*)/mi', $result, $matches); $cookies = array(); foreach($matches[1] as $item) { parse_str($item, $cookie); $cookies = array_merge($cookies, $cookie); } var_dump($cookies); |
尽管这个问题已经很老了,并且可接受的响应是有效的,但我发现它有点混乱,因为HTTP响应的内容(HTML,XML,JSON,二进制或其他)与标头混合在一起。
我找到了另一种选择。 CURL提供选项(
您可以使用如下代码(改编自TML响应):
1 2 3 4 5 6 7 8 9 10 11 12 13 | $cookies = Array(); $ch = curl_init('http://www.google.com/'); // Ask for the callback. curl_setopt($ch, CURLOPT_HEADERFUNCTION,"curlResponseHeaderCallback"); $result = curl_exec($ch); var_dump($cookies); function curlResponseHeaderCallback($ch, $headerLine) { global $cookies; if (preg_match('/^Set-Cookie:\\s*([^;]*)/mi', $headerLine, $cookie) == 1) $cookies[] = $cookie; return strlen($headerLine); // Needed by curl } |
该解决方案的缺点是使用全局变量,但是我想这对于短脚本来说不是问题。如果将curl包装到一个类中,则始终可以使用静态方法和属性。
这样做不需要regexp,但是需要PECL HTTP扩展名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 1); $result = curl_exec($ch); curl_close($ch); $headers = http_parse_headers($result); $cookobjs = Array(); foreach($headers AS $k => $v){ if (strtolower($k)=="set-cookie"){ foreach($v AS $k2 => $v2){ $cookobjs[] = http_parse_cookie($v2); } } } $cookies = Array(); foreach($cookobjs AS $row){ $cookies[] = $row->cookies; } $tmp = Array(); // sort k=>v format foreach($cookies AS $v){ foreach ($v AS $k1 => $v1){ $tmp[$k1]=$v1; } } $cookies = $tmp; print_r($cookies); |
如果您使用CURLOPT_COOKIE_FILE和CURLOPT_COOKIE_JAR,curl将在文件中读取cookie或将cookie写入文件。卷曲完成后,您可以根据需要读取和/或修改它。
libcurl还提供了CURLOPT_COOKIELIST,它提取所有已知的cookie。您需要做的就是确保PHP / CURL绑定可以使用它。
接受的答案似乎将搜索整个响应消息。如果单词" Set-Cookie"在行的开头,则可能会给您错误的Cookie标头匹配项。虽然在大多数情况下应该没问题。比较安全的方法可能是从头开始阅读消息,直到第一个空行指示消息头的结尾。这只是一个替代解决方案,应查找第一个空白行,然后在这些行上使用preg_grep,仅找到" Set-Cookie"。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | curl_setopt($ch, CURLOPT_HEADER, 1); //Return everything $res = curl_exec($ch); //Split into lines $lines = explode("\ ", $res); $headers = array(); $body =""; foreach($lines as $num => $line){ $l = str_replace("\ ","", $line); //Empty line indicates the start of the message body and end of headers if(trim($l) ==""){ $headers = array_slice($lines, 0, $num); $body = $lines[$num + 1]; //Pull only cookies out of the headers $cookies = preg_grep('/^Set-Cookie:/', $headers); break; } } |
这里的某人可能会觉得有用。 hhb_curl_exec2的工作原理与curl_exec非常相似,但是arg3是一个数组,该数组将填充返回的http标头(数字索引),而arg4是一个数组,该数组将填充返回的cookie($ cookies [" expires"] =>"星期五,2016年5月6日05:58:51")和arg5中将填充...有关curl发出的原始请求的信息。
缺点是它需要CURLOPT_RETURNTRANSFER处于打开状态,否则会出错,并且如果您已经将CURLOPT_STDERR和CURLOPT_VERBOSE用于其他用途,则它将覆盖CURLOPT_STDERR和CURLOPT_VERBOSE。
使用方法示例:
1 2 3 4 5 6 7 8 9 10 11 | <?php header("content-type: text/plain;charset=utf8"); $ch=curl_init(); $headers=array(); $cookies=array(); $debuginfo=""; $body=""; curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); $body=hhb_curl_exec2($ch,'https://www.youtube.com/',$headers,$cookies,$debuginfo); var_dump('$cookies:',$cookies,'$headers:',$headers,'$debuginfo:',$debuginfo,'$body:',$body); |
和功能本身
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | function hhb_curl_exec2($ch, $url, &$returnHeaders = array(), &$returnCookies = array(), &$verboseDebugInfo ="") { $returnHeaders = array(); $returnCookies = array(); $verboseDebugInfo =""; if (!is_resource($ch) || get_resource_type($ch) !== 'curl') { throw new InvalidArgumentException('$ch must be a curl handle!'); } if (!is_string($url)) { throw new InvalidArgumentException('$url must be a string!'); } $verbosefileh = tmpfile(); $verbosefile = stream_get_meta_data($verbosefileh); $verbosefile = $verbosefile['uri']; curl_setopt($ch, CURLOPT_VERBOSE, 1); curl_setopt($ch, CURLOPT_STDERR, $verbosefileh); curl_setopt($ch, CURLOPT_HEADER, 1); $html = hhb_curl_exec($ch, $url); $verboseDebugInfo = file_get_contents($verbosefile); curl_setopt($ch, CURLOPT_STDERR, NULL); fclose($verbosefileh); unset($verbosefile, $verbosefileh); $headers = array(); $crlf ="\\x0d\\x0a"; $thepos = strpos($html, $crlf . $crlf, 0); $headersString = substr($html, 0, $thepos); $headerArr = explode($crlf, $headersString); $returnHeaders = $headerArr; unset($headersString, $headerArr); $htmlBody = substr($html, $thepos + 4); //should work on utf8/ascii headers... utf32? not so sure.. unset($html); //I REALLY HOPE THERE EXIST A BETTER WAY TO GET COOKIES.. good grief this looks ugly.. //at least it's tested and seems to work perfectly... $grabCookieName = function($str) { $ret =""; $i = 0; for ($i = 0; $i < strlen($str); ++$i) { if ($str[$i] === ' ') { continue; } if ($str[$i] === '=') { break; } $ret .= $str[$i]; } return urldecode($ret); }; foreach ($returnHeaders as $header) { //Set-Cookie: crlfcoookielol=crlf+is%0D%0A+and+newline+is+%0D%0A+and+semicolon+is%3B+and+not+sure+what+else /*Set-Cookie:ci_spill=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22305d3d67b8016ca9661c3b032d4319df%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A14%3A%2285.164.158.128%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A109%3A%22Mozilla%2F5.0+%28Windows+NT+6.1%3B+WOW64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F43.0.2357.132+Safari%2F537.36%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1436874639%3B%7Dcab1dd09f4eca466660e8a767856d013; expires=Tue, 14-Jul-2015 13:50:39 GMT; path=/ Set-Cookie: sessionToken=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT; //Cookie names cannot contain any of the following '=,; \\t\ \ \\013\\014' // */ if (stripos($header,"Set-Cookie:") !== 0) { continue; /**/ } $header = trim(substr($header, strlen("Set-Cookie:"))); while (strlen($header) > 0) { $cookiename = $grabCookieName($header); $returnCookies[$cookiename] = ''; $header = substr($header, strlen($cookiename) + 1); //also remove the = if (strlen($header) < 1) { break; } ; $thepos = strpos($header, ';'); if ($thepos === false) { //last cookie in this Set-Cookie. $returnCookies[$cookiename] = urldecode($header); break; } $returnCookies[$cookiename] = urldecode(substr($header, 0, $thepos)); $header = trim(substr($header, $thepos + 1)); //also remove the ; } } unset($header, $cookiename, $thepos); return $htmlBody; } function hhb_curl_exec($ch, $url) { static $hhb_curl_domainCache =""; //$hhb_curl_domainCache=&$this->hhb_curl_domainCache; //$ch=&$this->curlh; if (!is_resource($ch) || get_resource_type($ch) !== 'curl') { throw new InvalidArgumentException('$ch must be a curl handle!'); } if (!is_string($url)) { throw new InvalidArgumentException('$url must be a string!'); } $tmpvar =""; if (parse_url($url, PHP_URL_HOST) === null) { if (substr($url, 0, 1) !== '/') { $url = $hhb_curl_domainCache . '/' . $url; } else { $url = $hhb_curl_domainCache . $url; } } ; curl_setopt($ch, CURLOPT_URL, $url); $html = curl_exec($ch); if (curl_errno($ch)) { throw new Exception('Curl error (curl_errno=' . curl_errno($ch) . ') on url ' . var_export($url, true) . ': ' . curl_error($ch)); // echo 'Curl error: ' . curl_error($ch); } if ($html === '' && 203 != ($tmpvar = curl_getinfo($ch, CURLINFO_HTTP_CODE)) /*203 is"success, but no output"..*/ ) { throw new Exception('Curl returned nothing for ' . var_export($url, true) . ' but HTTP_RESPONSE_CODE was ' . var_export($tmpvar, true)); } ; //remember that curl (usually) auto-follows the"Location:" http redirects.. $hhb_curl_domainCache = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL), PHP_URL_HOST); return $html; } |
我的理解是必须将