一個模糊的概念
無論是php,Python編程語言,還是Apache,Nginx服務器對于cgi協議是個繞不開的話題。安裝,部署都會經常的看到,那么它們到底是干什么的,網上的答案非常的多!今天通過它們進行一波匯總,徹底告別這個難關。參考: https://www.dayuzy.com/?p=476
HTTP到cgi協議
當瀏覽器的客戶端輸入網站走http協議到了web服務器,比如apache,這個大家都很清楚。web服務器沒有處理php文件的功能,就會請求php解釋器( php-cgi.exe )?;蛘?,不是PHP文件,比如是python文件,web服務器也會去請求python的解釋器。既然這么多解釋器,不能沒有一個協議規定它們的標準,否則亂套了,這時候 cgi協議就出來了 ,說白了就是 apache/nginx 和后端的腳本語言(php,python等)交互之間制定的協議。
php-cgi是什么
在windows系統上面,安裝了php后,在安裝目錄下面有下面三個文件:
php.exe php-cgi.exe php-win.exe
以上的三個文件互不影響,我本地測試刪除兩個另外一個也能用。
在命令行運行一個php文件
F:softwaresphpStudyPHPTutorialphpphp-7.2.1-nts> F:softwaresphpStudyPHPTutorialphpphp-7.2.1-nts> php F:softwaresphpStudyPHPTutorialindex.php Hello World #php.exe運行結果 F:softwaresphpStudyPHPTutorialphpphp-7.2.1-nts>php-cgi F:softwaresphpStudyPHPTutorialindex.php X-Powered-By: PHP/7.2.1 #php-cgi.exe運行結果 Content-type: text/html; charset=UTF-8 #php-cgi.exe運行結果 Hello World #php-cgi.exe運行結果 F:softwaresphpStudyPHPTutorialphpphp-7.2.1-nts>php-win F:softwaresphpStudyPHPTutorialindex.php #php-win.exe運行,結果是空行 F:softwaresphpStudyPHPTutorialphpphp-7.2.1-nts>
apache如何支持php
apache調用php有三種方式,模塊、cgi、FastCgi,這些方法網上都能找到,下面說明一下原理。
- 模塊:這是apache獨有的對php支持,nginx是沒有這種方式的,通過這種方式apache就可以直接處理php腳本了,至于是多進程、多線程要取決于apache的工作方式。參加: Apache三種工作模式介紹與配置
- cgi(通用網關接口):當apache有php腳本需要處理時,通過走cgi協議調用php解釋器 php-cgi.exe ,并且 php-cgi.exe 會讀取 php.ini 配置文件,作為apache的子進程。這里有個缺點:客戶端瀏覽器的請求多了,apache創建的子進程會特別多,并且每次都重新讀取 php.ini 配置文件。
- FastCgi就是為了解決cgi的問題,制定的協議。該協議規定, php-cgi.exe 我不再做你apache的子進程了,我獨立了,這樣你輕松了吧!我單獨構成一個服務,這個服務規定一個master主進程,再啟用幾個worker進程。master負責對 php.ini 等配置文件,以及接收apache發過來的請求,分配給worker進程進行處理。這樣就構成了 apache 作為客戶端, FastCgi協議程序 作為服務端。這個 FastCgi協議程序 就是PHP-fpm,它就是 FastCgi協議 的具體實現。
cgi和FastCgi是什么
它們都是協議,FastCgi解決了cgi的一些缺點。
php-cgi.exe和PHP-fpm是什么?
php-cgi.exe 是解釋器,也可以當作一個簡易的 cgi/FastCgi 管理器。比如在windows系統中nginx是如何與php結合的呢?linux通過php-fpm,但是windows沒有php-fpm,這個時候打開任務管理器會發現 CGI/FastCGI(32位) 這個進程,nginx就是反向代理給它的。
location ~ .php(.*)$ { fastcgi_pass 127.0.0.1:9000; #這里的9000端口就是``php-cgi.exe``監聽的 fastcgi_index index.php; fastcgi_split_path_info ^((?U).+.php)(/?.+)$; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; include fastcgi_params; }
我們在命令行查看一下 php-cgi.exe 的幫助,它也是可以進行一些簡單的配置的
F:softwaresphpStudyPHPTutorialphpphp-7.2.1-nts>php-cgi -h Usage: php [-q] [-h] [-s] [-v] [-i] [-f <file>] php <file> [args...] -a Run interactively -b <address:port>|<port> Bind Path for external FASTCGI Server mode -C Do not chdir to the script's directory -c <path>|<file> Look for php.ini file in this directory -n No php.ini file will be used -d foo[=bar] Define INI entry foo with value 'bar' -e Generate extended information for debugger/profiler -f <file> Parse <file>. Implies `-q' -h This help -i PHP information -l Syntax check only (lint) -m Show compiled in modules -q Quiet-mode. Suppress HTTP Header output. -s Display colour syntax highlighted source. -v Version number -w Display source with stripped comments and whitespace. -z <file> Load Zend extension <file>. -T <count> Measure execution time of script repeated <count> times.
php-fpm又是什么?
PHP-fpm 這個就是 FastCgi進程管理器 ,它的概念并不模糊!它啟動服務監聽端口,通過nginx反向代理給它,并且它自己內置php解釋器。但是,但是windows上面不能使用 PHP-fpm 。
對于客戶端瀏覽器而言, nginx/apache 是服務端。對于 PHP-fpm 而言, apache/nginx 是客戶端。
總結
cgi、fastcgi是協議,是標準,是web服務器到后臺腳本語言之間的協議。
php-cgi和PHP-fpm是程序,至于php-cgi是解釋器還是管理器,網上怎么說的也有,并且它也能監聽端口處理web服務器代理的請求,那它就是簡單的 cgi/FastCgi進程管理器 管理器吧!
參考
搞不清FastCgi與PHP-fpm之間是個什么樣的關系
PHP 連接方式介紹以及如何攻擊 PHP-FPM
php-cgi和php-fpm有什么關系?
Apache三種工作模式介紹與配置
php手冊:在舊的Windows系統上安裝
php-cgi和php-fpm有什么關系?