|
導(dǎo)讀網(wǎng)頁的本質(zhì)就是超級文本標記語言,通過結(jié)合使用其他的Web技術(shù)(如:腳本語言、公共網(wǎng)關(guān)接口、組件等),可以創(chuàng)造出功能強大的網(wǎng)頁。因而,超級文本標記語言是萬維網(wǎng)(Web)編程的基礎(chǔ),也就是說萬維網(wǎng)是建立... 網(wǎng)頁的本質(zhì)就是超級文本標記語言,通過結(jié)合使用其他的Web技術(shù)(如:腳本語言、公共網(wǎng)關(guān)接口、組件等),可以創(chuàng)造出功能強大的網(wǎng)頁。因而,超級文本標記語言是萬維網(wǎng)(Web)編程的基礎(chǔ),也就是說萬維網(wǎng)是建立在超文本基礎(chǔ)之上的。超級文本標記語言之所以稱為超文本標記語言,是因為文本中包含了所謂“超級鏈接”點。 在Windows環(huán)境下搭建了一個本地開發(fā)服務(wù)環(huán)境,使用Nginx做服務(wù),但是在使用file_get_contents()獲取本地的鏈接時出現(xiàn)了錯誤,下面的文章將給大家介紹關(guān)于這個問題的解決方法。一、問題說明在Windows環(huán)境下搭建了一個本地開發(fā)服務(wù)環(huán)境,使用Nginx做服務(wù),但是在使用file_get_contents()獲取本地的鏈接時http://127.0.0.1/index.php,出現(xiàn)了這樣的錯誤: 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環(huán)境為:nginx+php+mysql;于是找到這篇文章做個筆記,記錄下! 這兩天一直在搞windows下nginx+fastcgi的file_get_contents請求。我想,很多同學(xué)都遇到當(dāng)file_get_contents請求外網(wǎng)的http/https的php文件時毫無壓力,比如echo file_get_contents(‘http://www.baidu.com’) ,它會顯示百度的頁面。但當(dāng)你請求localhost/127.0.0.1本地網(wǎng)絡(luò)的php服務(wù)時卻一直是timeout,無論你將請求時間和腳本運行時間多長都無法返回數(shù)據(jù),如file_get_contents(‘http://localhost/phpinfo.php’) 。然而當(dāng)你嘗試請求html這樣的靜態(tài)文件時卻完全沒有問題。是什么原因呢?! 首先,我們知道file_get_contents/curl/fopen打開一個基于tcp/ip的http請求時,請求數(shù)據(jù)發(fā)送到nginx,而nginx則委托給php-cgi(fastcgi)處理php文件,一般情況fastcgi處理完一個php請求后會馬上釋放結(jié)束信號,等待下一個處理請求(當(dāng)然也有程序假死,一直占用資源的情況)。打開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;
}上面已經(jīng)清楚地看到,所有使用php結(jié)尾的文件都經(jīng)過fastcgi處理,而在php.ini的配置文件中也有一句: cgi.force_redirect = 1 表明,所有php程序安全地強制轉(zhuǎn)向交給cgi處理。 但在windows中,本地127.0.0.1:9000怎樣與php-cgi聯(lián)系的呢?!答案是增加一個php-cgi進程,用它來監(jiān)聽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進程監(jiān)聽來自127.0.0.1:9000 的請求。在dos命令下打開netstat –a就可以看到本地計算機下的9000端口處于listening狀態(tài)(也就是空置,如果沒有發(fā)送任何請求的話)。 好了,該說說在php中使用file_get_contents()、curl()、fopen()函數(shù)訪問localhost時為什么不能返回結(jié)果。我們再來試驗在index.php中加入file_get_contents(‘http://127.0.0.1/phpinfo.php’) 語句向phpinfo.php發(fā)送一個請求,這時瀏覽器中的狀態(tài)指示一直在打轉(zhuǎn),表示它一直在工作中。打開Dos中的netstat命令,可以看到本地的9000端口的狀態(tài)為:ESTABLISHED,表示該進程在聯(lián)機處理中。實際上,這里我們已經(jīng)同時向nginx發(fā)送了兩個基于http的php請求,一個是解析index.php,而另一個是phpinfo.php,這樣矛盾就出來了,因為我們的windows系統(tǒng)只加載了一個http進程,因此,它無法同時處理兩個php請求,它只能先處理第一個請求(index.php),而index.php卻又在等待phpinfo.php處理結(jié)果,phpinfo.php沒人幫它處理請求,因為它一直在等待index.php釋放結(jié)束信號,因此,造成了程序的阻塞狀態(tài),陷入了死循環(huán)。所以我們就看到了瀏覽器的狀態(tài)指示一直在打轉(zhuǎn)。Curl()與fopen函數(shù)的原因也相同。 二、解決方法找到了原因,我們也就有了解決辦法。 一是,向系統(tǒng)增加一個http請求,當(dāng)一個php-cig內(nèi)要加載另一個請求時,它能夠分配其它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可以分別處理不同的程序,比如: echo file_get_contents('http://localhost:8080/phpinfo.php');當(dāng)然,在*unix下有更多選擇,比如fork。 另外提醒下,網(wǎng)上有人說,通過去掉地址中的http://協(xié)議標記,而使用相對地址就規(guī)避函數(shù)的檢查,實際情況是不是這樣呢?!當(dāng)在index.php中使用file_get_contents(‘phpinfo.php’); 時,我們可以看到函數(shù)輸出了phpinfo.php的源代碼,相當(dāng)于file_get_contents(‘file:c:wwwphpinfo.php’); ,它實際上只是讀取你的文本內(nèi)容,因為file_get_contents()函數(shù)首先是處理file協(xié)議的,而curl則直接報錯無法解析。因此這些人純粹是不學(xué)無術(shù)的騙子。 還有人提出修改hosts文件,增加localhost www.xxx.com影射關(guān)系,函數(shù)通過www.xxx.com訪問本地php,這其實也是不治本的偏方,因為這只是方便計算機的dns解析,最終www.xxx.com交給127.0.0.1,而后者交給唯一http,還是阻塞。 相關(guān)推薦: file_get_contents函數(shù)不能使用的解決方法 PHP連接Nginx服務(wù)器并解析Nginx日志的方法 以上就是php服務(wù)nginx不能使用file_get_contents的解決方法的詳細內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章! 網(wǎng)站建設(shè)是一個廣義的術(shù)語,涵蓋了許多不同的技能和學(xué)科中所使用的生產(chǎn)和維護的網(wǎng)站。 |
溫馨提示:喜歡本站的話,請收藏一下本站!