所以其他公司的一些人认为如果不是使用soap或xml-rpc或其他合理的通信协议而是将其所有响应作为cookie嵌入标题中,那将是非常棒的.
我需要将这些cookie拉出来,希望这个卷曲响应中有一个数组.如果我不得不浪费我的一生为此写一个解析器,我会非常不高兴.
有谁知道如何简单地完成这项工作,最好不要在文件中写任何东西?
如果有人能帮我解决这个问题,我将非常感激.
$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提供了一个option(CURLOPT_HEADERFUNCTION
)来设置将为每个响应标题行调用的回调.该函数将接收curl对象和带有标题行的字符串.
您可以使用这样的代码(改编自TML响应):
$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包装到类中,您始终可以使用静态方法和属性.
这样做没有正则表达式,但需要PECL HTTP扩展.
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.完成卷曲后,您可以根据需要阅读和/或修改它.