web-dev-qa-db-fra.com

file_get_contents renvoie une chaîne vide

J'hésite à poser cette question car elle a l'air bizarre. Mais peu importe. Juste au cas où quelqu'un aurait déjà rencontré le même problème ... les fonctions du système de fichiers (fopem, file, file_get_contents) se comportent très étrangement pour http: // wrapper

  • cela fonctionne apparemment. aucune erreur déclenchée . fopen () renvoie une ressource.
  • il ne renvoie aucune donnée pour toutes les URL fonctionnant certainement (par exemple http://google.com/).
    le fichier renvoie un tableau vide, file_get_contents () renvoie une chaîne vide, fread renvoie false
  • pour toutes les URL intentionnellement erronées (par exemple http://goog973jd23le.com/) il se comporte exactement de la même manière, sauf pour un petit délai d'attente [supposément recherche de domaine], après quoi je n'obtiens aucune erreur (alors qu'il le devrait!) mais une chaîne vide.
  • url_fopen_wrapper est activé
  • curl (à la fois en ligne de commande et en version php) fonctionne correctement, tous les autres utilitaires et applications fonctionnent correctement, les fichiers locaux sont bien ouverts

Cette erreur semble inapplicable car dans mon cas, cela ne fonctionne pas pour chaque URL ou hôte.

php-fpm 5.2.11 Linux version 2.6.35.6-48.fc14.i686 ([email protected])

21
Your Common Sense

J'ai résolu ce problème sur mon serveur (exécutant PHP 5.3.3 sur Fedora 14) en supprimant le --with-curlwrapper de la configuration PHP et en le reconstruisant) .

23
Eric Caron

Cela ressemble à un bug. Mais juste pour la postérité, voici quelques choses que vous voudrez peut-être déboguer.

  • allow_url_fopen: déjà testé
  • PHP sous Apache pourrait se comporter différemment de PHP-CLI, et ferait allusion à chroot/selinux/fastcgi/etc. restrictions de sécurité
  • pare-feu local: improbable car curl fonctionne
  • blocage des agents utilisateurs: c'est assez courant en fait, les sites Web bloquent les robots d'exploration et les clients inconnus
  • proxy transparent de votre FAI, qui gêne ou bloque (l'agent utilisateur PHP ou l'agent non utilisateur peut être interprété comme un logiciel malveillant)
  • Problèmes de wrapper de flux PHP

Quoi qu'il en soit, commençons par prouver que les gestionnaires de flux PHP sont fonctionnels:

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

Essayez ensuite de voir si PHP fait de véritables requêtes HTTP. Ouvrez d'abord netcat sur la console:

nc -l 80000

Et déboguez avec juste:

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

Et à partir d'ici, vous pouvez essayer de communiquer avec PHP, voir si quelque chose revient si vous modifiez la réponse. Saisissez d'abord une réponse non valide dans netcat. S'il n'y a pas d'erreur levée, votre package PHP est borked.

(Vous pouvez également essayer de communiquer via une poignée "tcp: // ..".)

La prochaine étape consiste à expérimenter les paramètres de l'encapsuleur de flux http. Utilisez http://example.com/ littéralement, ce qui est connu pour fonctionner et ne jamais bloquer les agents utilisateurs.

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

Je pense que ignore_errors est très pertinent ici. Mais consultez http://www.php.net/manual/en/context.http.php et essayez spécifiquement de définir protocol_version à 1.1 (obtiendra une réponse fragmentée et mal interprétée, mais au moins nous verrons si n'importe quoi revient).

Si même cela ne réussit pas, essayez de pirater le wrapper http.

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

Cela définira non seulement l'agent utilisateur, mais injectera des en-têtes supplémentaires. S'il y a un problème de traitement avec la construction de la demande dans l'encapsuleur de flux http, cela pourrait éventuellement le détecter.

Sinon, essayez de désactiver toutes les extensions Zend, Suhosin , PHP xdebug, APC et d'autres modules de base. Il pourrait y avoir des interférences Sinon, il s'agit potentiellement d'un problème spécifique au package Fedora. Essayez une nouvelle version, voyez si elle persiste sur votre système.

16
mario

Lorsque vous utilisez l'encapsuleur de flux http PHP crée pour vous un tableau appelé $http_response_header après file_get_contents() (ou l'un des autres f famille de fonctions) est appelée. Elle contient des informations utiles sur l'état de la réponse. Pourriez-vous faire une var_dump() de ce tableau et voir si elle vous donne plus d'informations sur la réponse?

C'est une erreur vraiment bizarre que vous obtenez. La seule chose à laquelle je peux penser est que quelque chose d'autre sur le serveur bloque les requêtes http de PHP, mais je ne vois pas pourquoi cURL serait toujours ok ...

5
Jeremy

Le flux http est-il enregistré dans votre installation PHP? Recherchez "Registered PHP Streams" dans votre sortie phpinfo(). Le mien dit "https, ftps, compress.zlib, compress.bzip2, php, file, glob, data, http, ftp, phar, Zip ".

S'il n'y a pas de http, définissez allow_url_fopen à dans votre php.ini.

2