file_get_contents возвращает пустую строку - PullRequest
21 голосов
/ 13 ноября 2010

Я не решаюсь задать этот вопрос, потому что он выглядит странно. Но в любом случае. На всякий случай, если кто-то уже сталкивался с той же проблемой ... Функции файловой системы (fopem, file, file_get_contents) ведут себя очень странно для http: // wrapper

  • это похоже работает. ошибок не возникло . fopen () возвращает ресурс.
  • не возвращает данных для всех определённо работающих URL-адресов (например, http://google.com/).
    file возвращает пустой массив, file_get_contents () возвращает пустую строку, fread возвращает false
  • для всех преднамеренно неправильных URL-адресов (например, http://goog973jd23le.com/) он ведет себя точно так же, за исключением небольшого тайм-аута [предположительно поиска домена], после которого я получаю не ошибку (пока следует!), А пустую строку.
  • url_fopen_wrapper включен
  • curl (версия для командной строки и php) работает нормально, все остальные утилиты и приложения работают нормально, локальные файлы открываются нормально

Эта ошибка кажется неприменимой, потому что в моем случае она не работает для каждого URL или хоста.

php-fpm 5.2.11 Версия Linux 2.6.35.6-48.fc14.i686 (mockbuild@x86-18.phx2.fedoraproject.org)

Ответы [ 7 ]

23 голосов
/ 09 декабря 2010

Я исправил эту проблему на своем сервере (с PHP 5.3.3 на Fedora 14), удалив --with-curlwrapper из конфигурации PHP и перестроив его.

14 голосов
/ 22 ноября 2010

Звучит как ошибка. Но только для потомков вот несколько вещей, которые вы, возможно, захотите отладить.

  • allow_url_fopen: уже протестировано
  • PHP под Apache может вести себя иначе, чем PHP-CLI, и намекает на chroot / selinux / fastcgi / etc. ограничения безопасности
  • локальный брандмауэр: маловероятно, так как curl работает
  • блокировка агента пользователя: на самом деле это довольно часто, веб-сайты блокируют сканеры и неизвестных клиентов
  • прозрачный прокси от вашего провайдера, который либо искажает, либо блокирует (пользовательский агент PHP или не пользовательский агент может быть интерпретирован как вредоносное ПО)
  • Проблемы с PHP-оберткой

В любом случае, давайте сначала докажем, что обработчики потоков PHP работают:

<?php
     if (!file_get_contents("data:,ok")) {
          die("Houston, we have a stream wrapper problem.");
     }

Тогда попробуйте посмотреть, выполняет ли PHP реальные HTTP-запросы вообще. Сначала откройте netcat на консоли:

nc -l 80000

И отладка только с:

<?php
    print file_get_contents("http://localhost:8000/hello");

И отсюда вы можете попытаться связаться с PHP, посмотреть, вернется ли что-нибудь, если вы измените ответ. Сначала введите неверный ответ в netcat. Если нет ошибки, ваш пакет PHP не работает.

(Вы можете также попытаться связаться через дескриптор "tcp: // ..".)

Далее поэкспериментируем с параметрами оболочки потока http. Используйте буквально http://example.com/, который, как известно, работает и никогда не блокирует пользовательских агентов.

$context = stream_context_create(array("http"=>array(
    "method" => "GET",
    "header" => "Accept: xml/*, text/*, */*\r\n",
    "ignore_errors" => false,
    "timeout" => 50,
));

print file_get_contents("http://www.example.com/", false, $context, 0, 1000);

Я думаю ignore_errors здесь очень актуально. Но проверьте http://www.php.net/manual/en/context.http.php и, в частности, попытайтесь установить protocol_version на 1,1 (получит ответ с разбивкой на части и неправильно интерпретирует, но, по крайней мере, мы посмотрим, вернется ли что-нибудь ).

Если даже это не помогло, попробуйте взломать оболочку http.

<?php
    ini_set("user_agent" , "Mozilla/3.0\r\nAccept: */*\r\nX-Padding: Foo");

Это не только установит User-Agent, но и добавит дополнительные заголовки. Если при обработке запроса в оболочке потока http возникнет проблема с обработкой, это может в конечном итоге перехватить его.

В противном случае попробуйте отключить любые расширения Zend, Suhosin , PHP xdebug, APC и другие основные модули. Могут быть помехи. Иначе это потенциально проблема, специфичная для пакета Fedora. Попробуйте новую версию, посмотрите, сохраняется ли она в вашей системе.

4 голосов
/ 13 ноября 2010

Когда вы используете упаковщик потока http, PHP создает для вас массив с именем $http_response_header после вызова file_get_contents() (или любой другой функции семейства f). Содержит полезную информацию о состоянии ответа. Не могли бы вы сделать var_dump() этого массива и посмотреть, даст ли он вам больше информации об ответе?

Это действительно странная ошибка, которую вы получаете. Единственное, о чем я могу думать, это то, что что-то еще на сервере блокирует http-запросы от PHP, но тогда я не могу понять, почему cURL все еще будет в порядке ...

2 голосов
/ 17 ноября 2010

Зарегистрирован ли поток http в вашей установке PHP?Ищите «Зарегистрированные потоки PHP» в вашем phpinfo() выводе.Мой говорит: "https, ftps, compress.zlib, compress.bzip2, php, file, glob, data, http, ftp, phar, zip".

Если нет http, включите allow_url_fopen в вашем php.ini.

0 голосов
/ 28 июня 2012

У меня была такая же проблема в Windows после установки XAMPP 1.7.7. В конце концов мне удалось решить эту проблему, добавив следующую строку в php.ini (хотя allow_url_fopen = On):

расширение = php_openssl.dll

0 голосов
/ 22 ноября 2010

Что говорит вам тест с fsockopen ?

Изолирован ли тест от другого кода?

0 голосов
/ 18 ноября 2010

Используйте http://pear.php.net/reference/PHP_Compat-latest/__filesource/fsource_PHP_Compat__PHP_Compat-1.6.0a2CompatFunctionfile_get_contents.php.html, переименуйте его и проверьте, возникает ли ошибка с этой переписанной функцией.

...