PHP curl:curl_setopt()fopencookie失败

PHP curl:curl_setopt()fopencookie失败,php,curl,libcurl,fopen,Php,Curl,Libcurl,Fopen,我正在尝试编写一个脚本,该脚本将缓存图像,但遇到以下错误消息: 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 有人知道这里出了什么问题吗 我已经尝试过将/dev/n

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

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
有人知道这里出了什么问题吗

我已经尝试过将/dev/null和/或/tmp/cookies.txt设置/不设置CURLOPT_-COOKIEJARCURLOPT_-COOKIEFILE。我试过sudotouch/tmp/cookies.txt;sudo chown apache.apache/tmp/cookies.txt。这根本不管用

实际上我的脚本中不需要cookies,我很乐意在curl中禁用它们

我特意使用了fopen(…,“xb”),因此只有一个脚本实例会在我的真实脚本中写入缓存文件

我将CentOS 5.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);

}

?>

我认为问题在于
x
模式
fopen
x
一起使用时,如果文件已存在,则模式返回
false
。在您的情况下,该文件已经存在,
$fh
将为
false
,当它被传递到
curl\u setopt
时,您会收到此错误


若要解决此问题,请尝试将
xb
更改为
wb

如果您只需要一个脚本同时访问文件,则应使用
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)
}

感谢所有的回复,我最终得到了这个用于缓存图像的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);
}

?>


否,在第一次运行时,/tmp/yahoo.html不存在。我已经重写了我的代码,使它更清晰。它仍然失败(误导?)fopencookie错误消息。fopen(..,“xb”)对我来说是更好的选择,因为我只想下载一次图像(请参阅问题底部的真实脚本)。有了“cb”,它将被一次又一次地下载。另外,我认为当您使用“cb”时,不需要flock()。但无论如何,谢谢你的回答。我还在@Alex上提交了一个PHP错误。我已经修复了这个错误,它将出现在PHP5.3.4中,将于12月发布。我还没有测试,但我认为“cb”与“xb”会有相同的问题,即使用“cb”打开的文件也会出现fopencookie错误。我真的看不到有什么工作在这里,除了使用一个单独的带有“xb”的文件作为锁,如果fopen成功,请使用“wb”打开真正的文件。谢谢,我会坚持使用fopen(…,“wb”)和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)
}
<?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);
}

?>