PHP cURL 同时保存图像并获取 header 响应

标签 php image curl cookies captcha

我正在尝试使用 cURL 同时将图像保存到文件,同时还返回加载该文件进行保存时返回的 header 。

原因是因为每次加载和/或保存图像时都会生成一个唯一的 cookie,因此如果我保存文件,然后对同一图像 URL 执行另一个请求以获取 cookie,则该 cookie将无法与保存的图像正确配对(它是验证码图像)。

图像只能加载一次,并且在该图像的单次加载中必须同时保存(无需从服务器重新请求图像)显示标题,以便我可以获得加载和保存图像时生成的 cookie。

这就是我到目前为止所得到的,它确实返回 header 并保存文件,但当以 .jpg 形式查看时,该文件已损坏。如果我将文件类型更改为 .txt,我可以看到标题,但随后会出现一堆乱码,这些字符不是标题下方的图像。因此很明显,正在保存的文件是 header 和图像的组合,我只是无法单独获取它们,同时确保只有一个对图像的请求。

function getImageandCookie($ImageURL) {
    $rand = rand();
    $image_file = $_SERVER['DOCUMENT_ROOT'] . '/image/' . $GLOBALS['id'] . $rand . '.jpg';

    $fp = fopen ($image_file, 'w+');

    $ch = curl_init($ImageURL);

    curl_setopt($ch, CURLOPT_FILE, $fp);      
    curl_setopt($ch, CURLOPT_HEADER, 1);    
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);      
    curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36');

    $data = curl_exec($ch);

    curl_close($ch);
    fclose($fp); 
    return $data;
}

更多详情: 我正在尝试将图像保存到服务器上的文件中,同时将加载该图像时返回的 header 进行保存以供脚本的其余部分使用。

如果您加载此图片:http://ipv4.google.com/sorry/image?id=2125815723022350864&hl=en,您会看到创建了一个“绑定(bind)”到的 Cookie图像内的文本。如果您重新加载图像或向同一 URL 发出新请求,则会创建一个新的 Cookie 和图像“对”。

因此,我需要加载该图像一次并将其保存到文件中,同时抓取 header (因为这是“绑定(bind)”到该特定图像的 cookie 所在的位置),同时确保只请求该图像一次.

最佳答案

2小时后...

<?
//error_reporting(E_ALL);
//ini_set('display_errors', '1');

    $image_file = "captcha.jpg";
    //$cookie = "gcookie";

    $ch = curl_init("http://ipv4.google.com/sorry/image?id=2125815723022350864&hl=en");  
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    //curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
    //curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);      
    curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36');
    $data = curl_exec($ch);
    //split the header and body of request
    $matches = preg_split('/^\s*$/im', $data);
    $header = $matches[0];
    //extract cookie from header
    preg_match_all('/Set-Cookie: (.*?)\s+/i', $header, $gCookie, PREG_PATTERN_ORDER);
    $gCookie = $gCookie[1][0];
    echo $gCookie;
//GOOGLE_ABUSE_EXEMPTION=ID=a85908efa22e6f9b:TM=1429660423:C=c:IP=x.x.x.x-:S=APGng0vbHyNi1KCn9O1bnspO8BgF4LFEhQ;

    //The body is the image, we cleanup the header/body line break and save it
    $body = $matches[1] ;
    $body = implode("\n", array_slice(explode("\n", $body), 1));
    file_put_contents($image_file, $body);

curl_close($ch); 

理解后就不难了,当我们设置CURLOPT_HEADER, 1时,响应头就会进入$data =curl_exec($ch);,然后,我们只需需要拆分headerbody,找到header中的cookie并保存body(图像)到文件。

关于PHP cURL 同时保存图像并获取 header 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29783752/

相关文章:

php - 从 curl 响应中获取可用数组,该响应被格式化为 php 数组

php - 如何在 php 页面上显示存储在数据库中的图像?

php - 在移动设备上加载时使用 PHP 隐藏元素

PHP\MYSQL\AJAX(?) - 挣扎于如何在不调用页面刷新的情况下动态更新表单

php - AJAX 调用返回时图像不显示

image - 在 Unity 中无法更改黑色图像的颜色

ruby-on-rails - Ruby on Rails : DOcker : Is it feasible to build ROR project dependencies inside docker image

php - 有没有办法在从 php 服务器发送的 Firebase 通知中实现 "expiration"时间?

json - cURL 和错误 411(内容长度)

php - 交响乐团 5 : An unexpected value could not be normalized: stream resource