代码之家  ›  专栏  ›  技术社区  ›  Alexander Farber

php curl:curl_setopt()fopencookie失败

  •  0
  • Alexander Farber  · 技术社区  · 15 年前

    我正在尝试编写一个脚本,该脚本将缓存图像,但始终显示以下错误消息:

    Nov  4 12:55:19 centos httpd: PHP Fatal error:  curl_setopt() [<a href='function.curl-setopt'>function.curl-setopt</a>]: fopencookie failed in /var/www/html/proxy3.php on line 6
    

    我准备了一个更简单的脚本,但仍然存在这个问题:

    <?php
    #phpinfo();
    $fh = fopen('/tmp/yahoo.html', 'xb');
    if ($fh) {
            $ch = curl_init('http://www.yahoo.com/');
            curl_setopt($ch, CURLOPT_FILE, $fh); # XXX the line 6
            curl_setopt($ch, CURLOPT_HEADER, FALSE);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
            curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
            #curl_setopt($ch, CURLOPT_COOKIEJAR, '/dev/null');
            #curl_setopt($ch, CURLOPT_COOKIEFILE, '/dev/null');
            #curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
            #curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
            curl_exec($ch);
    
            if(!curl_errno($ch)) {
                     $info = curl_getinfo($ch);
                      echo 'Took '.$info['total_time'] .
                        's to send a request to '.$info['url'];
            }
            curl_close($ch);
            fclose($fh);
    } else {
            echo 'Can not open /tmp/yahoo.html';
    }
    ?>
    

    在/tmp目录中,我看到一个零大小的文件:

    afarber@centos:html> ls -alZ /tmp/yahoo.html
    -rw-r--r--  apache apache user_u:object_r:httpd_tmp_t      /tmp/yahoo.html
    

    有人能告诉我一个主意吗?这里出什么事了?

    我试过设置/不设置 冰壶 冰壶 -到/dev/null和/或到/tmp/cookies.txt。我试过了 sudo touch/tmp/cookies.txt;sudo chown apache.apache/tmp/cookies.txt 也是。这不管用。

    事实上,我的剧本里不需要饼干,我很乐意把它们弄得一团糟。

    我在用 FPEN…,“XB”) 这样,只有一个脚本实例将写入我的真实脚本中的缓存文件。

    我将Centos5.5与php-5.1.6-27.el5和未修改的php.ini结合使用

    谢谢您, 亚历克斯

    另外,这是我的真实图像代理脚本,它失败了,并显示了相同的fopencookie错误消息。我不能用 fopen(……‘wb’) 在那里,我 必须 使用 fOpen.(…)XB’ :

    <?php
    
    define('MIN_SIZE', 1024);
    define('MAX_SIZE', 1024 * 1024);
    define('CACHE_DIR', '/var/www/cached_avatars/');
    
    $img = urldecode($_GET['img']);
    # URL sanity checks omitted here for brevity
    $cached = CACHE_DIR . md5($img);
    $writefh = @fopen($cached, 'xb');
    # the file is not cached yet, download it!
    if ($writefh) {
            $ch = curl_init($img);
            curl_setopt($ch, CURLOPT_FILE, $writefh);
            curl_setopt($ch, CURLOPT_HEADER, FALSE);
            #curl_setopt($ch, CURLOPT_REFERER, $matches[1]);
            curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
            #curl_setopt($ch, CURLOPT_COOKIEJAR, '/dev/null');
            #curl_setopt($ch, CURLOPT_COOKIEFILE, '/dev/null');
            #curl_setopt($ch, CURLOPT_COOKIEJAR, CACHE_DIR . 'cookies.txt');
            #curl_setopt($ch, CURLOPT_COOKIEFILE, CACHE_DIR . 'cookies.txt');
            curl_exec($ch);
    
            $error    = curl_errno($ch);
            $length   = curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD);
            $mime     = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
            $is_image = ($mime != NULL &&
                         (stripos($mime, 'image/gif') !== FALSE ||
                          stripos($mime, 'image/png') !== FALSE ||
                          stripos($mime, 'image/jpg') !== FALSE ||
                          stripos($mime, 'image/jpeg') !== FALSE));
    
            curl_close($ch);
            fclose($writefh);
    
            if ($error || $length < MIN_SIZE || $length > MAX_SIZE || !$is_image) {
                    unlink($cached);
                    exit('Download failed: ' . $img);
            }
    } else {
            $finfo  = finfo_open(FILEINFO_MIME);
            $mime   = finfo_file($finfo, $cached);
            $length = filesize($cached);
            finfo_close($finfo);
    }
    
    $readfh = fopen($cached, 'rb');
    if ($readfh) {
            header('Content-Type: ' . $mime);
            header('Content-Length: ' . $length);
    
            while (!feof($readfh)) {
                    $buf = fread($readfh, 8192);
                    echo $buf;
            }
    
            fclose($readfh);
    
    }
    
    ?>
    
    3 回复  |  直到 13 年前
        1
  •  0
  •   codaddict    15 年前

    我认为问题是因为 x 模式。 fopen 当使用时 X 模式返回 false 如果文件已经存在。如果文件已经存在, $fh 当这个传到 curl_setopt 你会得到这个错误。

    要解决此问题,请尝试更改 xb wb .

        2
  •  0
  •   Artefacto    15 年前

    如果同时只需要一个脚本来访问文件,则应使用 cb 选项+ flock :

    $fh = fopen('/tmp/yahoo.html', 'cb');
    if (flock($fh, LOCK_EX | LOCK_NB) {
        //ftruncate($fh, 0); -- truncate the file if that's what you want
        //continue as usual
    }
    else {
        //could not obtain lock (without waiting)
    }
    
        3
  •  0
  •   Alexander Farber    15 年前

    感谢所有的响应,我最终得到了这个用于缓存图像的php/curl脚本(Flash应用程序需要它来绕过丢失的crossdomain.xml)-似乎可以与CentOS 5 Linux和php-5.1.6-27.el5一起工作:

    <?php
    
    define('MIN_SIZE', 512);
    define('MAX_SIZE', 1024 * 1024);
    define('CACHE_DIR', '/var/www/cached_avatars/');
    
    $img = urldecode($_GET['img']);
    # img sanity checks omitted here
    $cached = CACHE_DIR . md5($img);
    
    if (is_readable($cached)) {
            $finfo  = finfo_open(FILEINFO_MIME);
            $mime   = finfo_file($finfo, $cached);
            $length = filesize($cached);
            finfo_close($finfo);
    } else {
            $writefh = fopen($cached, 'wb');
            if ($writefh) {
                    flock($writefh, LOCK_EX);
                    $ch = curl_init($img);
                    curl_setopt($ch, CURLOPT_FILE, $writefh);
                    curl_setopt($ch, CURLOPT_HEADER, FALSE);
                    curl_setopt($ch, CURLOPT_REFERER, $matches[1]);
                    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
                    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
                    curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);
                    curl_exec($ch);
    
                    $error    = curl_errno($ch);
                    $length   = curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD);
                    $mime     = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
                    $is_image = ($mime != NULL &&
                                 (stripos($mime, 'image/gif') !== FALSE ||
                                  stripos($mime, 'image/png') !== FALSE ||
                                  stripos($mime, 'image/jpg') !== FALSE ||
                                  stripos($mime, 'image/jpeg') !== FALSE));
    
                    curl_close($ch);
                    fclose($writefh);
                    if ($error || $length < MIN_SIZE || $length > MAX_SIZE || !$is_image) {
                            unlink($cached);
                            exit('Download failed: ' . $img);
                    }
            }
    }
    
    $readfh = fopen($cached, 'rb');
    if ($readfh) {
            header('Content-Type: ' . $mime);
            header('Content-Length: ' . $length);
    
            flock($readfh, LOCK_SH);
    
            while (!feof($readfh)) {
                    $buf = fread($readfh, 8192);
                    echo $buf;
            }
    
            fclose($readfh);
    }
    
    ?>