摘要:全部視頻引入讀這篇文章之前請先閱讀源碼學(xué)習(xí)協(xié)議我們知道,客戶端之間通信的方式如下那么,我們今天詳細(xì)解釋一下圖中的協(xié)議的部分。協(xié)議就是為了解決協(xié)議的相關(guān)問題而出現(xiàn),是協(xié)議的升級版。在配置中指令中指定的值請求使用的協(xié)議,通常是或。
baiyan
全部視頻:https://segmentfault.com/a/11...
引入讀這篇文章之前請先閱讀【PHP源碼學(xué)習(xí)】2019-04-09 FastCGI協(xié)議1
我們知道,客戶端、nginx、PHP-FPM之間通信的方式如下:
那么,我們今天詳細(xì)解釋一下圖中的FastCGI協(xié)議的部分。其實,最開始我們是使用CGI協(xié)議的,但是CGI程序的弊端十分明顯,如需要新的進(jìn)程進(jìn)行數(shù)據(jù)處理,效率低下。FastCGI協(xié)議就是為了解決CGI協(xié)議的相關(guān)問題而出現(xiàn),是CGI協(xié)議的升級版。
我們學(xué)習(xí)一個協(xié)議,最重要的就是它的格式與語法,看它如何組織所要傳輸數(shù)據(jù)的格式,讓接收方能夠更加方便地接收。那么,這個協(xié)議需要解決如下幾個問題:
標(biāo)識一個請求的開始與結(jié)束,讓數(shù)據(jù)包在繁雜的TCP數(shù)據(jù)流中擁有清晰的邊界,方便讀取
傳輸其他附加參數(shù)(如定義在nginx中的fastcgi_param各項參數(shù))
傳輸一個客戶端發(fā)來請求的原始數(shù)據(jù)
針對上面一條提到在nginx配置文件中的其他附加參數(shù),有如下一些形式,大家應(yīng)該比較熟悉了:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;#腳本文件請求的路徑,也就是說當(dāng)訪問127.0.0.1/index.php的時候,需要讀取網(wǎng)站根目錄下面的index.php文件,如果沒有配置這一配置項時,nginx不回去網(wǎng)站根目錄下訪問.php文件,所以返回空白 fastcgi_param QUERY_STRING $query_string; #請求的參數(shù);如?app=123 fastcgi_param REQUEST_METHOD $request_method; #請求的動作(GET,POST) fastcgi_param CONTENT_TYPE $content_type; #請求頭中的Content-Type字段 fastcgi_param CONTENT_LENGTH $content_length; #請求頭中的Content-length字段。 fastcgi_param SCRIPT_NAME $fastcgi_script_name; #腳本名稱 fastcgi_param REQUEST_URI $request_uri; #請求的地址不帶參數(shù) fastcgi_param DOCUMENT_URI $document_uri; #與$uri相同。 fastcgi_param DOCUMENT_ROOT $document_root; #網(wǎng)站的根目錄。在server配置中root指令中指定的值 fastcgi_param SERVER_PROTOCOL $server_protocol; #請求使用的協(xié)議,通常是HTTP/1.0或HTTP/1.1。 fastcgi_param GATEWAY_INTERFACE CGI/1.1; #cgi 版本 fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; #nginx 版本號,可修改、隱藏 fastcgi_param REMOTE_ADDR $remote_addr; #客戶端IP fastcgi_param REMOTE_PORT $remote_port; #客戶端端口 fastcgi_param SERVER_ADDR $server_addr; #服務(wù)器IP地址 fastcgi_param SERVER_PORT $server_port; #服務(wù)器端口 fastcgi_param SERVER_NAME $server_name; #服務(wù)器名,域名在server配置中指定的server_name fastcgi_param PATH_INFO $path_info; #可自定義變量 -- PHP only, required if PHP was built with --enable-force-cgi-redirect fastcgi_param REDIRECT_STATUS 200;
那么,我們在PHP中即可打印出上面的服務(wù)環(huán)境變量。如:
echo $_SERVER["REMOTE_ADDR"]
帶著以上幾個問題,我們來由外到內(nèi)一步步剖析,為什么FastCGI協(xié)議是這樣設(shè)計的。
FastCGI的設(shè)計思想與結(jié)構(gòu)首先我們基于之前的客戶端、nginx、PHP-FPM之間通信流程圖,放大nginx與PHP-FPM之間通信的數(shù)據(jù)流:
為了解決我們之前談到的三個問題,F(xiàn)astCGI把包分為多種類型,每種類型做它自己的事情。如圖中的FCGI_BEGIN_REQUEST類型,負(fù)責(zé)標(biāo)識請求的開始,F(xiàn)CGI_PARAMS類型負(fù)責(zé)發(fā)送nginx中配置的參數(shù),F(xiàn)CGI_STDIN類型存儲客戶端發(fā)送的原始字節(jié)流數(shù)據(jù)。這樣一次請求的所有數(shù)據(jù)才能夠成功送達(dá)到PHP-FPM。我們看一下FastCGI數(shù)據(jù)包的所有類型:
#define FCGI_BEGIN_REQUEST 1 //(web->fastcgi)請求開始數(shù)據(jù)包 #define FCGI_ABORT_REQUEST 2 //(web->fastcgi)終止請求 #define FCGI_END_REQUEST 3 //(fastcgi->web)請求結(jié)束 #define FCGI_PARAMS 4 //(web->fastcgi)傳遞參數(shù) #define FCGI_STDIN 5 //(web->fastcgi)數(shù)據(jù)流傳輸數(shù)據(jù) #define FCGI_STDOUT 6 //(fastcgi->web)數(shù)據(jù)流傳輸數(shù)據(jù) #define FCGI_STDERR 7 //(fastcgi->web)數(shù)據(jù)流傳輸 #define FCGI_DATA 8 //(web->fastcgi)數(shù)據(jù)流傳輸 #define FCGI_GET_VALUES 9 //(web->fastcgi)查詢fastcgi服務(wù)器性能參數(shù) #define FCGI_GET_VALUES_RESULT 10 //(fastcgi->web)fastcgi性能參數(shù)查詢返回 #define FCGI_UNKNOWN_TYPE 11 #define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE)
我們從宏觀層面看完了FastCGI包,我們深入每個包的內(nèi)部結(jié)構(gòu)。通過上一篇筆記的學(xué)習(xí)我們知道,TCP/IP等協(xié)議的數(shù)據(jù)包,通常都是數(shù)據(jù)包頭部+包體的結(jié)構(gòu),頭部字段通常是一些描述信息,包體才真正地存儲數(shù)據(jù),這里FastCGI協(xié)議也不例外:
在代碼層面,它的結(jié)構(gòu)如下:
typedef struct _fcgi_begin_request_rec { fcgi_header hdr; //包頭部 fcgi_begin_request body; //包體 } fcgi_begin_request_rec;FastCGI數(shù)據(jù)包頭部
FastCGI數(shù)據(jù)包頭部結(jié)構(gòu)定義如下:
typedef struct { unsigned char version; // 協(xié)議版本號 unsigned char type; // 數(shù)據(jù)包類型 unsigned char requestIdB1; // 包唯一標(biāo)識id的高8位 unsigned char requestIdB0; // 包唯一標(biāo)識id的低8位 unsigned char contentLengthB1; // 記錄內(nèi)容長度高8位(body長度高8位) unsigned char contentLengthB0; // 記錄內(nèi)容長度低8位(body長度低8位) unsigned char paddingLength; // 補(bǔ)齊位長度(body補(bǔ)齊長度) unsigned char reserved; // 字節(jié)補(bǔ)齊位 }Header;
通常情況下,每一個FastCGI數(shù)據(jù)包都有一個頭部,大小為8個字節(jié),用來記錄當(dāng)前數(shù)據(jù)包的一些輔助信息,如數(shù)據(jù)包類型(需要確認(rèn)當(dāng)前包屬于剛才我們列舉的哪種類型)、唯一標(biāo)識包的id、還有包體的長度、以及字節(jié)對齊(確保是2的整數(shù)次冪)
雖然在通常情況下,每一種FastCGI類型的數(shù)據(jù)包都有相同結(jié)構(gòu)的包頭,但是它們之間包體部分的結(jié)構(gòu)就不太一樣了。
下面我們以一個請求從nginx到PHP-FPM的數(shù)據(jù)包流動方向(FCGI_BEGIN_REQUEST->FCGI_PARAMS->FCGI_STDIN)為例,講解一下FastCGI協(xié)議的類型。
FCGI_BEGIN_REQUEST類型FCGI_BEGIN_REQUEST類型的數(shù)據(jù)包代表一個請求數(shù)據(jù)包的開始
由于數(shù)據(jù)包頭部的結(jié)構(gòu)已經(jīng)介紹完畢了,接下來我們看一下FCGI_BEGIN_REQUEST類型包體部分的結(jié)構(gòu),它是一個結(jié)構(gòu)體:
typedef struct _fcgi_begin_request { unsigned char roleB1; // unsigned char roleB0; unsigned char flags; unsigned char reserved[5]; } fcgi_begin_request;
FCGI_BEGIN_REQUEST的包體大小為8個字節(jié),其中role字段是為了描述當(dāng)前需要FastCGI服務(wù)器(即 PHP-FPM)充當(dāng)?shù)慕巧蠪CGI_RESPONDER,F(xiàn)CGI_AUTHORIZER 和FCGI_FILTER。
FCGI_RESPONDER:最常見的動態(tài)語言腳本處理角色,叫做響應(yīng)器。FCGI_PARAMS類型
FCGI_AUTHORIZER:用于判斷請求是否擁有訪問權(quán)限,類似于HTTP請求中的認(rèn)證功能,叫做授權(quán)器。
FCGI_FILTER:用于對一些特殊的數(shù)據(jù)進(jìn)行處理并返回,包括添加數(shù)據(jù)頭部與尾部等功能,叫做過濾器(官方對其沒有過多的介紹,所以無法詳細(xì)描述)。
大多數(shù)請求我們都是使用FCGI_RESPONDER角色進(jìn)行請求傳輸,因為動態(tài)語言可以完全的替代其他2中角色的功能,所以授權(quán)器和過濾器的功能被大家給遺忘了。不過這不代表角色的設(shè)定是錯誤的,角色的設(shè)定很大一部分程度上給Fastcgi協(xié)議提供了快捷擴(kuò)展的功能,保證了協(xié)議的可擴(kuò)展性。
flags則是用于設(shè)置使用傳輸時復(fù)用通道,避免每次傳輸都需要新開一個socket通道來浪費時間和性能。
在nginx配置文件中,配置的FastCGI的參數(shù)均以參數(shù)名-值的形式出現(xiàn),那么可以用一種key-value對的結(jié)構(gòu)來對其進(jìn)行存儲,而它確實也是這樣設(shè)計的:
我們可以大體上看出,F(xiàn)CGI_PARAMS的包體以key-value對形式出現(xiàn)。整個數(shù)據(jù)包的存儲數(shù)據(jù)為包頭部、key的長度、value的長度、key數(shù)據(jù)、value數(shù)據(jù)的順序出現(xiàn)。
這里它用了一個技巧。為了節(jié)省空間,當(dāng)key或者value的數(shù)據(jù)長度小于等于127字節(jié)的時候,key和value的長度兩個字段采用1個字節(jié)來表示;當(dāng)大于128字節(jié)的時候,采用4個字節(jié)來表示。那么為什么選127作為分界線呢?因為127的二進(jìn)制位01111111,從128開始,最高為為1,所以只需要判斷最高位是否為1,就可以知道key或者value長度的字段占用1個字節(jié)還是4個字節(jié)。如果最高位為1,則占用4個字節(jié);如果最高位為0,則占用1個字節(jié)。
FCGI_STDIN類型FCGI_STDIN存儲從客戶端發(fā)出的原始數(shù)據(jù),注意這里的數(shù)據(jù)是以字節(jié)流存儲的,而并不是存在一個固定的結(jié)構(gòu)體中:
至此,一次nginx到PHP-FPM的請求就完成了。
抓包示例13:50:43.883594 IP VM_0_3_centos.33844 > VM_0_3_centos.cslistener: Flags [P.], seq 608546014:608546982, ack 2973795482, win 342, options [nop,nop,TS val 961901286 ecr 961901286], length 968 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. 0x0010: 03fc de3d 4000 4006 5abc 7f00 0001 7f00 ...=@.@.Z....... 0x0020: 0001 8434 2328 2445 acde b140 849a 8018 ...4#($E...@.... 0x0030: 0156 01f1 0000 0101 080a 3955 72e6 3955 .V........9Ur.9U 0x0040: 72e6 0101 0001 0008 0000 0001 0000 0000 r............... 0x0050: 0000 0104 0001 03a0 0000 0f35 5343 5249 ...........5SCRI 0x0060: 5054 5f46 494c 454e 414d 452f 6461 7461 PT_FILENAME/data 0x0070: 2f77 7777 2f68 7464 6f63 732f 6461 7461 /www/htdocs/data 0x0080: 2f77 7777 2f68 7464 6f63 732f 736e 6f2f /www/htdocs/sno/ 0x0090: 7075 626c 6963 2f69 6e64 6578 2e70 6870 public/index.php 0x00a0: 0c00 5155 4552 595f 5354 5249 4e47 0e03 ..QUERY_STRING.. 0x00b0: 5245 5155 4553 545f 4d45 5448 4f44 4745 REQUEST_METHODGE 0x00c0: 540c 0043 4f4e 5445 4e54 5f54 5950 450e T..CONTENT_TYPE. 0x00d0: 0043 4f4e 5445 4e54 5f4c 454e 4754 480b .CONTENT_LENGTH. 0x00e0: 0a53 4352 4950 545f 4e41 4d45 2f69 6e64 .SCRIPT_NAME/ind 0x00f0: 6578 2e70 6870 0b01 5245 5155 4553 545f ex.php..REQUEST_ 0x0100: 5552 492f 0c01 444f 4355 4d45 4e54 5f55 URI/..DOCUMENT_U 0x0110: 5249 2f0d 2b44 4f43 554d 454e 545f 524f RI/.+DOCUMENT_RO 0x0120: 4f54 2f64 6174 612f 7777 772f 6874 646f OT/data/www/htdo 0x0130: 6373 2f64 6174 612f 7777 772f 6874 646f cs/data/www/htdo 0x0140: 6373 2f73 6e6f 2f70 7562 6c69 630f 0853 cs/sno/public..S 0x0150: 4552 5645 525f 5052 4f54 4f43 4f4c 4854 ERVER_PROTOCOLHT 0x0160: 5450 2f31 2e31 0e04 5245 5155 4553 545f TP/1.1..REQUEST_ 0x0170: 5343 4845 4d45 6874 7470 1107 4741 5445 SCHEMEhttp..GATE 0x0180: 5741 595f 494e 5445 5246 4143 4543 4749 WAY_INTERFACECGI 0x0190: 2f31 2e31 0f0c 5345 5256 4552 5f53 4f46 /1.1..SERVER_SOF 0x01a0: 5457 4152 456e 6769 6e78 2f31 2e31 312e TWAREnginx/1.11. 0x01b0: 390b 0f52 454d 4f54 455f 4144 4452 3131 9..REMOTE_ADDR11 0x01c0: 332e 3232 372e 3234 392e 3132 370b 0552 3.227.249.127..R 0x01d0: 454d 4f54 455f 504f 5254 3533 3931 330b EMOTE_PORT53913. 0x01e0: 0a53 4552 5645 525f 4144 4452 3137 322e .SERVER_ADDR172. 0x01f0: 3136 2e30 2e33 0b02 5345 5256 4552 5f50 16.0.3..SERVER_P 0x0200: 4f52 5438 300b 0d53 4552 5645 525f 4e41 ORT80..SERVER_NA 0x0210: 4d45 6772 6170 652e 7961 662e 636f 6d0f MEgrape.yaf.com. 0x0220: 0352 4544 4952 4543 545f 5354 4154 5553 .REDIRECT_STATUS 0x0230: 3230 3009 0f48 5454 505f 484f 5354 3132 200..HTTP_HOST12 0x0240: 322e 3135 322e 3232 392e 3232 310f 0a48 2.152.229.221..H 0x0250: 5454 505f 434f 4e4e 4543 5449 4f4e 6b65 TTP_CONNECTIONke 0x0260: 6570 2d61 6c69 7665 1209 4854 5450 5f43 ep-alive..HTTP_C 0x0270: 4143 4845 5f43 4f4e 5452 4f4c 6d61 782d ACHE_CONTROLmax- 0x0280: 6167 653d 301e 0148 5454 505f 5550 4752 age=0..HTTP_UPGR 0x0290: 4144 455f 494e 5345 4355 5245 5f52 4551 ADE_INSECURE_REQ 0x02a0: 5545 5354 5331 0f79 4854 5450 5f55 5345 UESTS1.yHTTP_USE 0x02b0: 525f 4147 454e 544d 6f7a 696c 6c61 2f35 R_AGENTMozilla/5 0x02c0: 2e30 2028 4d61 6369 6e74 6f73 683b 2049 .0.(Macintosh;.I 0x02d0: 6e74 656c 204d 6163 204f 5320 5820 3130 ntel.Mac.OS.X.10 0x02e0: 5f31 355f 3029 2041 7070 6c65 5765 624b _15_0).AppleWebK 0x02f0: 6974 2f35 3337 2e33 3620 284b 4854 4d4c it/537.36.(KHTML 0x0300: 2c20 6c69 6b65 2047 6563 6b6f 2920 4368 ,.like.Gecko).Ch 0x0310: 726f 6d65 2f37 352e 302e 3337 3730 2e31 rome/75.0.3770.1 0x0320: 3030 2053 6166 6172 692f 3533 372e 3336 00.Safari/537.36 0x0330: 0b76 4854 5450 5f41 4343 4550 5474 6578 .vHTTP_ACCEPTtex 0x0340: 742f 6874 6d6c 2c61 7070 6c69 6361 7469 t/html,applicati 0x0350: 6f6e 2f78 6874 6d6c 2b78 6d6c 2c61 7070 on/xhtml+xml,app 0x0360: 6c69 6361 7469 6f6e 2f78 6d6c 3b71 3d30 lication/xml;q=0 0x0370: 2e39 2c69 6d61 6765 2f77 6562 702c 696d .9,image/webp,im 0x0380: 6167 652f 6170 6e67 2c2a 2f2a 3b71 3d30 age/apng,*/*;q=0 0x0390: 2e38 2c61 7070 6c69 6361 7469 6f6e 2f73 .8,application/s 0x03a0: 6967 6e65 642d 6578 6368 616e 6765 3b76 igned-exchange;v 0x03b0: 3d62 3314 0d48 5454 505f 4143 4345 5054 =b3..HTTP_ACCEPT 0x03c0: 5f45 4e43 4f44 494e 4767 7a69 702c 2064 _ENCODINGgzip,.d 0x03d0: 6566 6c61 7465 140e 4854 5450 5f41 4343 eflate..HTTP_ACC 0x03e0: 4550 545f 4c41 4e47 5541 4745 7a68 2d43 EPT_LANGUAGEzh-C 0x03f0: 4e2c 7a68 3b71 3d30 2e39 0104 0001 0000 N,zh;q=0.9...... 0x0400: 0000 0105 0001 0000 0000 ..........
根據(jù)上一篇筆記我們學(xué)到的數(shù)據(jù)包結(jié)構(gòu),我們能夠?qū)?shù)據(jù)包分解為以下結(jié)構(gòu)(加粗的數(shù)字為首部長度,乘以4就是總字節(jié)數(shù)):
MAC幀頭部(14字節(jié)):0000 0000 0000 0000 0000 0000 0800
IP頭部(20字節(jié)):4500 03fc de3d 4000 4006 5abc 7f00 0001 7f00
TCP頭部(32字節(jié)):8434(33844端口) 2328(9000端口) 2445 acde b140 849a 8018 0156 01f1 0000 0101 080a 3955 72e6 3955 72e6
接下來就是FastCGI協(xié)議數(shù)據(jù)包的部分了,首先應(yīng)該是一個FCGI_BEGIN_REQUEST類型的數(shù)據(jù)包:
包頭:0101 0001 0008 0000
version:01(FastCGI協(xié)議版本為1)
type:01(對應(yīng)FCGI_BEGIN_REQUEST)
requestIdB1:00
requestIdB0:01(代表是1號數(shù)據(jù)包)
contentLengthB1:00
contentLengthB0:08(代表包體占用8個字節(jié))
paddingLength:00(補(bǔ)齊位長度為0)
reserved:00(對齊位無效)
包體:0001 0000 0000 0000
roleB1:1(代表充當(dāng)?shù)氖琼憫?yīng)器角色)
roleB0:0
flags:0
reserved[5]:0(對齊位無效)
那么接下來應(yīng)該是一個FCGI_PARAMS類型的數(shù)據(jù)包了:
包頭:0104 0001 03a0 0000
version:01
type:04(對應(yīng)FCGI_PARAMS)
requestIdB1:00
requestIdB0:01(代表是1號數(shù)據(jù)包)
contentLengthB1:03
contentLengthB0:a0(代表包體占用928個字節(jié))
paddingLength:00(補(bǔ)齊位長度為0)
reserved:00(對齊位無效)
由于這個包體是非常長的,我們選擇其中一個key-value對:
包體:0f 35
緊挨著包頭的應(yīng)該是存儲key長度的字段,既然它最高位為0(0=0000),那么key的長度只需用1個字節(jié)存儲,長度為15字節(jié)(0f)。然后緊挨著的應(yīng)該是存儲value長度的字段,它的最高位也為0(3=0011),故value的長度也需要1個字節(jié)存儲,長度為53字節(jié)。
然后緊挨著的應(yīng)該是key的內(nèi)容:5343 5249 5054 5f46 494c 454e 414d 45,一共15字節(jié),根據(jù)ASCII碼翻譯之后,其值為SCRIPT_FILENAME。再往下數(shù)53個字節(jié),應(yīng)該就是value的內(nèi)容:2f 6461 7461 2f77 7777 2f68 7464 6f63 732f 6461 7461 2f77 7777 2f68 7464 6f63 732f 736e 6f2f 7075 626c 6963 2f69 6e64 6578 2e70 6870,其翻譯后的值為/data/www/htdocs/data/www/htdocs/sno/public/index.php。
我們往下繼續(xù)數(shù),直至第928個字節(jié),還有其他的各項參數(shù),我們在此不再一一列舉。然后就是FCGI_STDIN類型的數(shù)據(jù)包,存儲著我們客戶端的原始數(shù)據(jù)。我們再此就不再贅述,有興趣的同學(xué)可以繼續(xù)跟進(jìn)一下。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/40540.html
摘要:此文用于匯總跟隨陳雷老師及團(tuán)隊的視頻,學(xué)習(xí)源碼過程中的思考整理與心得體會,此文會不斷更新視頻傳送門每日學(xué)習(xí)記錄使用錄像設(shè)備記錄每天的學(xué)習(xí)源碼學(xué)習(xí)源碼學(xué)習(xí)內(nèi)存管理筆記源碼學(xué)習(xí)內(nèi)存管理筆記源碼學(xué)習(xí)內(nèi)存管理筆記源碼學(xué)習(xí)基本變量筆記 此文用于匯總跟隨陳雷老師及團(tuán)隊的視頻,學(xué)習(xí)源碼過程中的思考、整理與心得體會,此文會不斷更新 視頻傳送門:【每日學(xué)習(xí)記錄】使用錄像設(shè)備記錄每天的學(xué)習(xí) PHP7...
摘要:所以,它就會將端口號還有一些額外的信息被稱作首部,和應(yīng)用層下發(fā)的數(shù)據(jù)部分進(jìn)行封裝,一起傳給下一層即網(wǎng)絡(luò)層。它們之間的通信,屬于同一機(jī)器上不同端口號之間的通信。而協(xié)議傳輸?shù)膬H僅是無意義的字節(jié)流數(shù)據(jù),接收方并不能正確讀取數(shù)據(jù)的含義。 baiyan 全部視頻:https://segmentfault.com/a/11... 計算機(jī)網(wǎng)絡(luò)架構(gòu)的分層與封裝 我們經(jīng)常談到,計算機(jī)網(wǎng)絡(luò)有多種體系架構(gòu)...
摘要:,配是通過一個類似的協(xié)議,升級版的的。在上有幫你管理進(jìn)程,在似乎沒有,這是有點令人悲傷的。檢驗一下然后開啟然后配置中里文件在盤建立一個的文件夾,放入,開啟測試寫入訪問應(yīng)用我的項目就用了這個東西,,歡迎 fastcgi As we all know,nginx配php是通過fastcgi(一個類似http的協(xié)議,升級版的cgi)的。在linux上有php-fpm幫你管理進(jìn)程,在windo...
閱讀 2309·2023-04-26 00:01
閱讀 805·2021-10-27 14:13
閱讀 1835·2021-09-02 15:11
閱讀 3388·2019-08-29 12:52
閱讀 538·2019-08-26 12:00
閱讀 2572·2019-08-26 10:57
閱讀 3413·2019-08-26 10:32
閱讀 2854·2019-08-23 18:29