File_get_contents возвращает пустую строку

Я не решаюсь задавать этот вопрос, потому что это выглядит странно. Но в любом случае. На всякий случай кто-то столкнулся с той же проблемой уже... функции файловой системы (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 ([email protected])

Ответы

Ответ 1

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

Ответ 2

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

  • allow_url_fopen: уже протестировано
  • PHP под Apache может вести себя иначе, чем PHP-CLI, и намекнул бы на chroot/selinux/fastcgi/etc. ограничения безопасности
  • локальный брандмауэр: маловероятно, поскольку curl works
  • блокировка пользовательского агента: это довольно часто, сайты блокируют сканеры и неизвестные клиенты
  • прозрачный прокси-сервер от вашего интернет-провайдера, который либо управляет, либо блокирует (пользовательский агент или не-пользовательский агент 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 (получится chunked и неверно истолкованный ответ, но, по крайней мере, мы увидим если что-то возвращается).

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

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

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

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

Ответ 3

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

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

Ответ 4

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

Если нет http, установите allow_url_fopen для включения в php.ini.

Ответ 5

Что скажет вам тест fsockopen?

Является ли тест изолированным от другого кода?

Ответ 6

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

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