2010-11-04 4 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 

делает ybody, пожалуйста, подумайте, что здесь происходит неправильно?

Я пробовал настройки/не устанавливать CURLOPT_COOKIEJAR и CURLOPT_COOKIEFILE - к/DEV/нуль и/или /tmp/cookies.txt. Я пробовал sudo touch /tmp/cookies.txt; sudo chown apache.apache /tmp/cookies.txt тоже. Это просто не работает.

На самом деле мне не нужны файлы cookie в моем скрипте, я был бы рад отключить их в curl.

Я использую fopen (..., «xb») специально, чтобы только один экземпляр сценария записывал в кешированный файл в моем реальном скрипте.

Я использую CentOS 5.5 с PHP-5.1.6-27.el5 и немодифицированного php.ini

Спасибо, Alex

P.S. И вот мой реальный сценарий прокси-образа, который терпит неудачу с тем же сообщением об ошибке fopencookie. Я не могу использовать FOPEN (...., 'термометр') там, я обязательно использование Еореп (.... 'хь'):

<?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-скрипт для кэширования изображений (требуется Вспышка приложение, чтобы обойти недостающую 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 mode возвращает false, если файл уже существует. В вашем случае файл уже существует, $fh будет false, и когда это будет передано curl_setopt, вы получите эту ошибку.

Чтобы исправить это, попробуйте изменить xb на wb.

+0

Нет, на 1-й запуск /tmp/yahoo.html не существует. Я переписал свой код, чтобы сделать его более понятным. Это все еще не удается с сообщением об ошибке (вводящим в заблуждение?) Fopencookie. –

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» он будет загружен снова и снова.Кроме того, я думаю, что flock() не требуется, когда вы используете «cb». Но в любом случае, спасибо за ваш ответ. Я также подал ошибку PHP на http://bugs.php.net/bug.php?id=53241 –

+1

@Alex Я исправил ошибку, она будет в PHP 5.3.4, которая должна состояться в декабре , Я не тестировал, но я думаю, что «cb» будет иметь ту же проблему, что и «xb», то есть файл, открытый с помощью «cb», также даст ошибку fopencookie. Я действительно не вижу работы здесь, кроме использования отдельного файла с «xb» в качестве блокировки и их, если fopen успешно, откройте реальный с помощью «wb». – Artefacto

+0

Спасибо, я буду придерживаться использования fopen (..., 'wb') и flock() так долго. –

Смежные вопросы