2010-11-04 150 views
0

我試圖寫一個腳本,這將緩存圖像,但我堅持了以下錯誤消息:PHP捲曲:curl_setopt()fopencookie的失敗

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目錄然後我看到一個零大小的文件:

[email protected]:html> ls -alZ /tmp/yahoo.html 
-rw-r--r-- apache apache user_u:object_r:httpd_tmp_t  /tmp/yahoo.html 

的是否大家請有想法,這裏有什麼問題?

我試過設置/不設置CURLOPT_COOKIEJARCURLOPT_COOKIEFILE - 到/ dev/null的和/或/tmp/cookies.txt。我試過sudo touch /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); 

} 

?> 

回答

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); 
} 

?> 
0

我認爲這個問題是由於x模式。 fopen當與x模式一起使用時,如果該文件已存在,則返回false。在你的情況下,文件已經存在,$fh將是false,當這傳遞給curl_setopt你會得到這個錯誤。

要解決此問題,請嘗試將xb更改爲wb

+0

不,在第一次運行/tmp/yahoo.html不存在。我重寫了我的代碼,使其更加清晰。它仍然失敗(錯誤?)fopencookie錯誤消息。 – 2010-11-04 12:44:48

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) 
} 
+0

fopen(....,「xb」)對我來說是更好的選擇,因爲我只想下載一次圖片(請參閱我的問題底部的實際腳本)。使用「cb」它將被一次又一次地下載。另外,當你使用「cb」時,我認爲不需要flock()。但無論如何,謝謝你的回答。我還在http://bugs.php.net/bug.php?id=53241 – 2010-11-04 16:15:18

+1

@Alex上提交了一個PHP錯誤我修正了這個錯誤,它將在PHP 5.3.4中,這是由於12月。我沒有測試過,但我認爲'cb'與'xb'會有同樣的問題,即用'cb'打開的文件也會給出fopencookie錯誤。除了使用'xb'作爲鎖的單獨文件以及如果fopen成功,我真的無法在這裏看到解決方法,用'wb'打開真正的文件。 – Artefacto 2010-11-05 01:45:50

+0

謝謝,我會堅持使用fopen(...,'wb')和flock()這麼久。 – 2010-11-05 12:02:40