Maison  >  Article  >  développement back-end  >  Le service PHP nginx ne peut pas utiliser la solution file_get_contents

Le service PHP nginx ne peut pas utiliser la solution file_get_contents

不言
不言original
2018-09-07 14:35:413103parcourir

J'ai construit un environnement de service de développement local dans un environnement Windows et utilisé Nginx comme service. Cependant, une erreur s'est produite lors de l'utilisation de file_get_contents() pour obtenir le lien local. L'article suivant vous présentera la solution à ce problème.

1. Description du problème

Un environnement de service de développement local a été construit dans un environnement Windows et Nginx a été utilisé comme service. Cependant, lors de l'utilisation de file_get_contents() pour obtenir le lien local http. ://127.0.0.1/index.php, une telle erreur s'est produite :

file_get_contents(http://127.0.0.1/index.php) [<a href=&#39;function.file-get-contents&#39;>function.file-get-contents</a>]: failed to open stream: HTTP request failed!

L'environnement PHP de l'ordinateur local est : nginx+php+mysql ; j'ai donc trouvé cet article et pris une note, enregistrez-le ; !

Au cours des deux derniers jours, j'ai fait des requêtes file_get_contents pour nginx+fastcgi sous Windows. Je pense que de nombreux étudiants n'ont rencontré aucune pression lorsque file_get_contents demande des fichiers php http/https sur le réseau externe, comme echo file_get_contents('http://www.baidu.com'), qui affichera la page de Baidu. Mais lorsque vous demandez le service PHP sur le réseau local localhost/127.0.0.1, il affiche toujours un délai d'attente. Quelle que soit la durée pendant laquelle vous définissez l'heure de la requête et la durée d'exécution du script, vous ne pouvez pas renvoyer de données, telles que file_get_contents('http: //localhost/phpinfo.php' ). Cependant, il n'y a aucun problème lorsque vous essayez de demander des fichiers statiques tels que HTML. Quelle est la raison ? !

Tout d'abord, nous savons que lorsque file_get_contents/curl/fopen ouvre une requête http basée sur tcp/ip, les données de la requête sont envoyées à nginx, et nginx confie à php-cgi (fastcgi) le traitement du php. En général, fastcgi Après avoir traité une requête PHP, le signal de fin sera immédiatement libéré, en attendant la prochaine requête de traitement (bien sûr, il existe également des cas où le programme se bloque et continue d'occuper des ressources). Ouvrez nginx.conf, on voit la ligne suivante :

location ~ .php {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  d:/www/htdocs$fastcgi_script_name;
        include        fastcgi_params;
}

On a bien vu ci-dessus que tous les fichiers se terminant par php sont traités par fastcgi, et il y a aussi une phrase dans le fichier de configuration de php. ini :

cgi.force_redirect = 1

indique que tous les programmes PHP peuvent forcer en toute sécurité la redirection vers CGI pour le traitement.

Mais sous Windows, comment le local 127.0.0.1:9000 contacte-t-il php-cgi ? ! La réponse est d'ajouter un processus php-cgi et de l'utiliser pour écouter sur 127.0.0.1:9000. Grâce à la commande du contrôleur :

RunHiddenConsole.exe D:/www/php/php-cgi.exe  -b 127.0.0.1:9000 -c C:/WINDOWS/php.ini

nous pouvons démarrer un processus php-cgi.exe pour écouter les requêtes de 127.0.0.1:9000 lors du démarrage de Windows. Ouvrez netstat -a sous la commande dos et vous pourrez voir que le port 9000 sous l'ordinateur local est en état d'écoute (c'est-à-dire vide, si aucune demande n'est envoyée).

D'accord, il est temps d'expliquer pourquoi les résultats ne peuvent pas être renvoyés lors de l'utilisation des fonctions file_get_contents(), curl() et fopen() en PHP pour accéder à localhost. Essayons d'ajouter l'instruction file_get_contents('http://127.0.0.1/phpinfo.php') à index.php pour envoyer une requête à phpinfo.php. À ce moment, l'indicateur d'état du navigateur continue de tourner, indiquant qu'il est activé. a été Au travail. Ouvrez la commande netstat dans Dos et vous pouvez voir que l'état du port 9000 local est : ESTABLISHED, indiquant que le processus est en cours de traitement en ligne. En fait, ici, nous avons envoyé deux requêtes php basées sur http à nginx en même temps, l'une consiste à analyser index.php et l'autre est phpinfo.php, donc la contradiction apparaît, car notre système Windows ne charge qu'un seul http. Par conséquent, il ne peut pas traiter deux requêtes php en même temps. Il ne peut traiter que la première requête (index.php) en premier, tandis que index.php attend le résultat du traitement de phpinfo.php et que personne ne l'aide. traiter la requête phpinfo.php, car il attend que index.php libère le signal de fin, provoquant ainsi le blocage du programme et sa chute dans une boucle infinie. Nous voyons donc l’indicateur d’état du navigateur tourner tout le temps. La raison des fonctions Curl() et fopen est la même.

2. Solution

Une fois qu'on a trouvé la raison, on a aussi une solution.

Tout d'abord, ajoutez une requête http au système Lorsqu'une autre requête est chargée dans un php-cig, il peut allouer un autre http pour gérer la requête php supplémentaire. À ce stade, vous devez attribuer un port différent à un autre serveur http, tel que 8080. Le cas de nginx est le suivant :

http {  
    server {  
        listen          80;  
        server_name     127.0.0.1;  
        location / {  
            index index.php;  
            root  /web/www/htdocs;  
        }  
    }  
    server {  
        listen          8080;  
        server_name     127.0.0.1;  
        location / {  
            index index.html;  
            root  /web/www/htdocs;  
        }  
    }  
    include    /opt/nginx/conf/vhosts/php.conf;  
}

De cette manière, les ports 80 et 8080 peuvent gérer respectivement différents programmes, tels que :
test.php

 echo file_get_contents('http://localhost:8080/phpinfo.php');

De bien sûr, sous *unix Il y a plus d'options, comme fork.

Pour rappel, certaines personnes sur Internet ont déclaré qu'en supprimant la marque du protocole http:// dans l'adresse et en utilisant des adresses relatives, les contrôles de fonction pouvaient être contournés. Est-ce réellement le cas ? ! Lors de l'utilisation de file_get_contents('phpinfo.php'); dans index.php, nous pouvons voir que la fonction génère le code source de phpinfo.php, qui est équivalent à file_get_contents('file:c:wwwphpinfo.php');, qui en fait, ce qui précède lit simplement votre contenu texte, car la fonction file_get_contents() traite d'abord le protocole de fichier, et curl signale directement une erreur et ne peut pas être analysée. Par conséquent, ces gens sont simplement des menteurs ignorants.

Certaines personnes ont également proposé de modifier le fichier hosts et d'ajouter la relation d'allusion localhost www.xxx.com La fonction accède au PHP local via www.xxx.com. C'est en fait un remède qui ne guérit pas le problème. cause première, car cela ne convient que pour la résolution DNS de l'ordinateur, finalement www.xxx.com est transmis à 127.0.0.1, et ce dernier est transmis au seul http, qui est toujours bloqué.

Recommandations associées :

Solution au problème selon lequel la fonction file_get_contents ne peut pas être utilisée

Comment connecter le serveur Nginx avec PHP et analyser les journaux Nginx

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn