• 技术文章 >后端开发 >php教程

    php服务nginx不能使用file_get_contents的解决方法

    不言不言2018-09-07 14:35:41原创1924
    在Windows环境下搭建了一个本地开发服务环境,使用Nginx做服务,但是在使用file_get_contents()获取本地的链接时出现了错误,下面的文章将给大家介绍关于这个问题的解决方法。

    一、问题说明

    在Windows环境下搭建了一个本地开发服务环境,使用Nginx做服务,但是在使用file_get_contents()获取本地的链接时http://127.0.0.1/index.php,出现了这样的错误:

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

    本地电脑php环境为:nginx+php+mysql;于是找到这篇文章做个笔记,记录下!

    这两天一直在搞windows下nginx+fastcgi的file_get_contents请求。我想,很多同学都遇到当file_get_contents请求外网的http/https的php文件时毫无压力,比如echo file_get_contents(‘http://www.baidu.com’) ,它会显示百度的页面。但当你请求localhost/127.0.0.1本地网络的php服务时却一直是timeout,无论你将请求时间和脚本运行时间多长都无法返回数据,如file_get_contents(‘http://localhost/phpinfo.php’) 。然而当你尝试请求html这样的静态文件时却完全没有问题。是什么原因呢?!

    首先,我们知道file_get_contents/curl/fopen打开一个基于tcp/ip的http请求时,请求数据发送到nginx,而nginx则委托给php-cgi(fastcgi)处理php文件,一般情况fastcgi处理完一个php请求后会马上释放结束信号,等待下一个处理请求(当然也有程序假死,一直占用资源的情况)。打开nginx.conf,我们看到下面这一行:

    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;
    }

    上面已经清楚地看到,所有使用php结尾的文件都经过fastcgi处理,而在php.ini的配置文件中也有一句:

    cgi.force_redirect = 1

    表明,所有php程序安全地强制转向交给cgi处理。

    但在windows中,本地127.0.0.1:9000怎样与php-cgi联系的呢?!答案是增加一个php-cgi进程,用它来监听127.0.0.1:9000。通过控制器命令:

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

    我们就可以在启动windows时,开启一个php-cgi.exe进程监听来自127.0.0.1:9000 的请求。在dos命令下打开netstat –a就可以看到本地计算机下的9000端口处于listening状态(也就是空置,如果没有发送任何请求的话)。

    好了,该说说在php中使用file_get_contents()、curl()、fopen()函数访问localhost时为什么不能返回结果。我们再来试验在index.php中加入file_get_contents(‘http://127.0.0.1/phpinfo.php’) 语句向phpinfo.php发送一个请求,这时浏览器中的状态指示一直在打转,表示它一直在工作中。打开Dos中的netstat命令,可以看到本地的9000端口的状态为:ESTABLISHED,表示该进程在联机处理中。实际上,这里我们已经同时向nginx发送了两个基于http的php请求,一个是解析index.php,而另一个是phpinfo.php,这样矛盾就出来了,因为我们的windows系统只加载了一个http进程,因此,它无法同时处理两个php请求,它只能先处理第一个请求(index.php),而index.php却又在等待phpinfo.php处理结果,phpinfo.php没人帮它处理请求,因为它一直在等待index.php释放结束信号,因此,造成了程序的阻塞状态,陷入了死循环。所以我们就看到了浏览器的状态指示一直在打转。Curl()与fopen函数的原因也相同。

    二、解决方法

    找到了原因,我们也就有了解决办法。

    一是,向系统增加一个http请求,当一个php-cig内要加载另一个请求时,它能够分配其它http处理额外的php请求。这时需给另一个http sever分配不同的端口,比如8080。nginx的案例如下:

    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;  
    }

    这样,端口80与8080可以分别处理不同的程序,比如:
    test.php

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

    当然,在*unix下有更多选择,比如fork。

    另外提醒下,网上有人说,通过去掉地址中的http://协议标记,而使用相对地址就规避函数的检查,实际情况是不是这样呢?!当在index.php中使用file_get_contents(‘phpinfo.php’); 时,我们可以看到函数输出了phpinfo.php的源代码,相当于file_get_contents(‘file:c:wwwphpinfo.php’); ,它实际上只是读取你的文本内容,因为file_get_contents()函数首先是处理file协议的,而curl则直接报错无法解析。因此这些人纯粹是不学无术的骗子。

    还有人提出修改hosts文件,增加localhost www.xxx.com影射关系,函数通过www.xxx.com访问本地php,这其实也是不治本的偏方,因为这只是方便计算机的dns解析,最终www.xxx.com交给127.0.0.1,而后者交给唯一http,还是阻塞。

    相关推荐:

    file_get_contents函数不能使用的解决方法

    PHP连接Nginx服务器并解析Nginx日志的方法

    php入门到就业线上直播课:查看学习

    以上就是php服务nginx不能使用file_get_contents的解决方法的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。

    前端(VUE)零基础到就业课程:点击学习

    清晰的学习路线+老师随时辅导答疑

    自己动手写 PHP MVC 框架:点击学习

    快速了解MVC架构、了解框架底层运行原理

    上一篇:php输出中文页面时出现中文乱码的解决方案 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • ❤️‍🔥共22门课程,总价3725元,会员免费学• ❤️‍🔥接口自动化测试不想写代码?• PHP预定义变量9大超全局数组用法详解_php基础• PHP查询附近的人及其距离的实现方法• php使用curl并发减少后端访问时间的方法分析• php通过smtp邮件验证登陆的方法_php技巧• php mysql_real_escape_string函数用法与实例教程_php基础• PHP文件上传主要代码讲解_php基础• PHP的基本常识小结_php基础• php数据访问之增删改查操作_php技巧
    1/1

    PHP中文网