摘要:然而當你嘗試請求這樣的靜態文件時卻完全沒有問題。打開中的命令,可以看到本地的端口的狀態為,表示該進程在聯機處理中。與函數的原因也相同。這時需給另一個分配不同的端口,比如。因此這些人純粹是不學無術的騙子。
注意:本文為轉載,原文鏈接:Windows下PHP服務nginx不能使用file_get_contents/curl/fopen的原因!一、問題說明
在Windows環境下搭建了一個本地開發服務環境,使用Nginx做服務,但是在使用file_get_contents()獲取本地的鏈接時http://127.0.0.1/index.php,出現了這樣的錯誤:
file_get_contents(http://127.0.0.1/index.php) [function.file-get-contents]: 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,還是阻塞。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/40119.html
摘要:然而當你嘗試請求這樣的靜態文件時卻完全沒有問題。打開中的命令,可以看到本地的端口的狀態為,表示該進程在聯機處理中。與函數的原因也相同。這時需給另一個分配不同的端口,比如。因此這些人純粹是不學無術的騙子。 注意:本文為轉載,原文鏈接:Windows下PHP服務nginx不能使用file_get_contents/curl/fopen的原因! 一、問題說明 在Windows環境下搭建了一...
摘要:等平臺平臺由于我開發以為主,所以就用的環境配置來學習。啟動進程的用戶和用戶組,進程運行的用戶必須要設置。模式模式,表示啟動進程是動態分配的,隨著請求量動態變化的。 centos等linux平臺 /usr/local/php/php /usr/local/php/etc/php.ini /usr/local/php/sbin/php-fpm /usr/local/php/etc/php-...
摘要:等平臺平臺由于我開發以為主,所以就用的環境配置來學習。啟動進程的用戶和用戶組,進程運行的用戶必須要設置。模式模式,表示啟動進程是動態分配的,隨著請求量動態變化的。 centos等linux平臺 /usr/local/php/php /usr/local/php/etc/php.ini /usr/local/php/sbin/php-fpm /usr/local/php/etc/php-...
閱讀 3652·2021-09-02 15:11
閱讀 4563·2021-08-16 10:47
閱讀 1560·2019-08-29 18:35
閱讀 3030·2019-08-28 17:54
閱讀 2843·2019-08-26 11:37
閱讀 1496·2019-08-23 16:51
閱讀 1799·2019-08-23 14:36
閱讀 1801·2019-08-23 14:21