傳送門在這https://www.cnblogs.com/wanghetao/p/3934350.html
當我們在談到cgi的時候,我們在討論什麼
最早的Web服務器簡單地響應瀏覽器發來的HTTP請求,並將存儲在服務器上的HTML文件返回給瀏覽器,也就是靜態html。事物總是不 斷髮展,網站也越來越複雜,所以出現動態技術。但是服務器並不能直接運行 php,asp這樣的文件,自己不能做,外包給別人吧,但是要與第三做個約定,我給你什麼,然後你給我什麼,就是握把請求參數發送給你,然後我接收你的處 理結果給客戶端。那這個約定就是 common gateway interface,簡稱cgi。這個協議可以用vb,c,php,python 來實現。cgi只是接口協議,根本不是什麼語言。下面圖可以看到流程:
WEB服務器與cgi程序交互
WEB服務器將根據CGI程序的類型決定數據向CGI程序的傳送方式,一般來講是通過標準輸入/輸出流和環境變量來與CGI程序間傳遞數據。 如下圖所示:
CGI程序通過標準輸入(STDIN)和標準輸出(STDOUT)來進行輸入輸出。此外CGI程序還通過環境變量來得到輸入,操作系統提供了許 多環境變量,它們定義了程序的執行環境,應用程序可以存取它們。Web服務器和CGI接口又另外設置了一些環境變量,用來向CGI程序傳遞一些重要的參 數。CGI的GET方法還通過環境變量QUERY-STRING向CGI程序傳遞Form中的數據。 下面是一些常用的CGI環境變量:
變量名 | 描述 |
---|---|
CONTENT_TYPE | 這個環境變量的值指示所傳遞來的信息的MIME類型。目前,環境變量CONTENT_TYPE一般都是:application/x-www-form-urlencoded,他表示數據來自於HTML表單。 |
CONTENT_LENGTH | 如果服務器與CGI程序信息的傳遞方式是POST,這個環境變量即使從標準輸入STDIN中可以讀到的有效數據的字節數。這個環境變量在讀取所輸入的數據時必須使用。 |
HTTP_COOKIE | 客戶機內的 COOKIE 內容。 |
HTTP_USER_AGENT | 提供包含了版本數或其他專有數據的客戶瀏覽器信息。 |
PATH_INFO | 這個環境變量的值表示緊接在CGI程序名之後的其他路徑信息。它常常作爲CGI程序的參數出現。 |
QUERY_STRING | 如果服務器與CGI程序信息的傳遞方式是GET,這個環境變量的值即使所傳遞的信息。這個信息經跟在CGI程序名的後面,兩者中間用一個問號'?'分隔。 |
REMOTE_ADDR | 這個環境變量的值是發送請求的客戶機的IP地址,例如上面的192.168.1.67。這個值總是存在的。而且它是Web客戶機需要提供給Web服務器的唯一標識,可以在CGI程序中用它來區分不同的Web客戶機。 |
REMOTE_HOST | 這個環境變量的值包含發送CGI請求的客戶機的主機名。如果不支持你想查詢,則無需定義此環境變量。 |
REQUEST_METHOD | 提供腳本被調用的方法。對於使用 HTTP/1.0 協議的腳本,僅 GET 和 POST 有意義。 |
SCRIPT_FILENAME | CGI腳本的完整路徑 |
SCRIPT_NAME | CGI腳本的的名稱 |
SERVER_NAME | 這是你的 WEB 服務器的主機名、別名或IP地址。 |
SERVER_SOFTWARE | 這個環境變量的值包含了調用CGI程序的HTTP服務器的名稱和版本號。例如,上面的值爲Apache/2.2.14(Unix) |
一個例子
下面是test.php代碼:
-
<?php
-
function test()
-
{
-
$data = $_SERVER["QUERY_STRING"];
-
if (isset($data)) {
-
var_dump($data);
-
echo("Hello cgi!");
-
}
-
}
-
test();
訪問http://127.0.0.1/test/test.php?a=1&b=2結果爲:
string 'a=1&b=2' (length=7)
Hello cgi!
通過php中的超全局變量$_SERVER["QUERY_STRING"]獲取get方式提交的內容,如果想獲取post提交的內容可以通過$_POST["變量名"],上面例子展示了cgi 程序與web服務器的交互。
cgi 與 fastcgi
CGI工作原理:每當客戶請求CGI的時候,WEB服務器就請求操作系統生成一個新的CGI解釋器進程(如php-cgi.exe),CGI 的一個進程則處理完一個請求後退出,下一個請求來時再創建新進程。當然,這樣在訪問量很少沒有併發的情況也行。可是當訪問量增大,併發存在,這種方式就不 適合了。於是就有了fastcgi。
FastCGI像是一個常駐(long-live)型的CGI,它可以一直執行着,只要激活後,不會每次都要花費時間去fork一次(這是CGI最爲人詬病的fork-and-execute 模式)。
一般情況下,FastCGI的整個工作流程是這樣的:
1.Web Server啓動時載入FastCGI進程管理器(IIS ISAPI或Apache Module)
2.FastCGI進程管理器自身初始化,啓動多個CGI解釋器進程(可見多個php-cgi)並等待來自Web Server的連接。
3.當客戶端請求到達Web Server時,FastCGI進程管理器選擇並連接到一個CGI解釋器。 Web server將CGI環境變量和標準輸入發送到FastCGI子進程php-cgi。
4.FastCGI 子進程完成處理後將標準輸出和錯誤信息從同一連接返回Web Server。當FastCGI子進程關閉連接時, 請求便告處理完成。FastCGI子進程接着等待並處理來自FastCGI進程管理器(運行在Web Server中)的下一個連接。 在CGI模式中,php-cgi在此便退出了。
PHP-FPM與Spawn-FCGI
Spawn-FCGI是一個通用的FastCGI管理服務器,它是lighttpd中的一部份,很多人都用Lighttpd的Spawn-FCGI進行FastCGI模式下的管理工作。 但是有缺點,於是PHP-fpm就是針對於PHP的,Fastcgi的一種實現,他負責管理一個進程池,來處理來自Web服務器的請求。目前,PHP-fpm是內置於PHP的。
apache 模塊方式
在xp 配置 apache + php ,會在apache 配置下面一段:
LoadModule php5_module C:/php/php5apache2_2.dll
當PHP需要在Apache服務器下運行時,一般來說,它可以模塊的形式集成, 此時模塊的作用是接收Apache傳遞過來的PHP文件請求,並處理這些請求, 然後將處理後的結果返回給Apache。如果我們在Apache啓動前在其配置文件中配置好了PHP模塊, PHP模塊通過註冊apache2的ap_hook_post_config掛鉤,在Apache啓動的時候啓動此模塊以接受PHP文件的請求。
Apache 的Hook機制是指:Apache 允許模塊(包括內部模塊和外部模塊,例如mod_php5.so,mod_perl.so等)將自定義的函數注入到請求處理循環中。 換句話說,模塊可以在Apache的任何一個處理階段中掛接(Hook)上自己的處理函數,從而參與Apache的請求處理過程。 mod_php5.so/ php5apache2.dll就是將所包含的自定義函數,通過Hook機制注入到Apache中,在Apache處理流程的各個階段負責處理php請 求。
有人測試nginx+PHP-FPM在高併發情況下可能會達到Apache+mod_php5的5~10倍,所以現在nginx+PHP-FPM使用的人越來越多。
感覺原作者寫的很棒就稍加修改成自己熟悉的,傳送門在這https://www.cnblogs.com/wanghetao/p/3934350.html