我正在尝试编写一个可以缓存图像的脚本,但是我遇到了以下错误信息:
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
请有人知道,这里出了什么问题?
我已尝试将 CURLOPT_COOKIEJAR 和 CURLOPT_COOKIEFILE 设置/设置为/ dev / null和/或设置为/tmp/cookies.txt。我试过 sudo touch /tmp/cookies.txt; sudo chown apache.apache /tmp/cookies.txt 也是。这不行。
实际上我的脚本中不需要cookie,我很乐意在卷曲中禁用它们。
我故意使用 fopen(...,“xb”),因此只有一个脚本实例会在我的真实脚本中写入缓存文件。
我使用的是带有php-5.1.6-27.el5的CentOS 5.5和未经修改的php.ini
谢谢你, 亚历
P.S。这是我的真实图像代理脚本,它失败了同样的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);
}
?>
答案 0 :(得分:0)
我认为问题是因为x
模式。 fopen
与x
模式一起使用时,如果文件已存在,则返回false
。在您的情况下,该文件已存在,$fh
将为false
,当传递给curl_setopt
时,您会收到此错误。
要解决此问题,请尝试将xb
更改为wb
。
答案 1 :(得分:0)
如果您想要的只是一个同时访问该文件的脚本,则应使用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)
}
答案 2 :(得分:0)
感谢所有回复,我最终得到了这个用于缓存图像的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);
}
?>