PHP核心SAPI探究實例分享
PHP作為一門簡單而強大的語言,能夠提供許多Web適用的語言特性。從實踐出發,繼弱類型變數原理探究後,王帥將繼續帶大家弄清楚PHP核心中一些常用的部分,本期則是SAPI的深入理解。
SAPI是Server Application Programming Interface(伺服器應用程式介面)的縮寫。 PHP透過SAPI提供了一組接口,供應用和PHP核心之間進行資料交互。
簡單的講,就像函數的輸入和輸出一樣,我們透過Linux命令列執行一段PHP程式碼,本質是Linux的Shell透過PHP的SAPI傳入一組參數,Zend引擎執行後,返回給shell,由shell顯示出來的過程。同樣的,透過Apache呼叫PHP,透過Web伺服器給SAPI傳入數據,Zend引擎執行後,回傳給Apache,由Apache顯示在頁面上。
圖1. PHP架構圖
PHP提供很多形式的接口,包括apache、apache2filter、apache2handler、caudium、cgi 、cgi-fcgi、cli、cli-server、 continuity、embed、isapi、litespeed、milter、nsapi、phttpd pi3web、roxen、thttpd、tux和webjames。但常用的只有5種形式,CLI/CGI(命令列)、Multiprocess(多重進程)、Multithreaded(多執行緒)、FastCGI和Embedded(內嵌)。
PHP提供了一個函數來檢視目前SAPI介面類型:
string php_sapi_name ( void )
PHP的運行與載入
#無論使用哪一種SAPI,在PHP執行腳本前後,都包含一系列事件:Module的Init(MINT)和Shutdown(MSHUTDOWN),Request 的Init(RINT)和Shutdown(RSHUTDOWN)。 第一階段是PHP模組初始化階段(MINT),可以初始化擴展內部變數、分配資源和註冊資源處理器,在整個PHP實例生命週期內,該過程只執行一次。
什麼是PHP模組?透過上面的PHP架構圖,在PHP中可以使用get_loaded_extensions 函數來查看所有編譯並載入的模組/擴展,相當於CLI模式下的php -m。
以PHP的Memcached擴充原始碼為例:
PHP_MINIT_FUNCTION(memcached) { zend_class_entry ce; memcpy(&memcached_object_handlers,zend_get_std_object_handlers(), sizeof(zend_object_handlers)); memcached_object_handlers.clone_obj = NULL; /* 执行了一些类似的初始化操作 */ return SUCCESS; }
第二階段是請求初始化階段(RINT),在模組初始化並啟動後,會建立PHP運行環境,同時呼叫所有模組註冊的RINT函數,呼叫每個擴充的請求初始化函數,設定特定的環境變數、分配資源或執行其他任務,如審核。
PHP_RINIT_FUNCTION(memcached) { /* 执行一些关于请求的初始化 */ return SUCCESS; }
第三階段,請求處理完成後,會呼叫PHP_RSHUTDOWN_FUNCTION進行回收,這是每個擴充的請求關閉函數,執行最後的清理工作。 Zend引擎執行清理過程、垃圾收集、對先前的請求期間所用到的每個變數執行unset。請求完成可能是執行到腳本完成,也可能是呼叫die()或exit()函數完成
第四階段,當PHP生命週期結束時候,PHP_MSHUTDOWN_FUNCTION對模組進行回收處理,這是每個擴展的模組關閉函數,用於關閉自己的核心子系統。
PHP_MSHUTDOWN_FUNCTION(memcached) { /* 执行关于模块的销毁工作 */ UNREGISTER_INI_ENTRIES(); return SUCCESS; }
常見的運行模式
常見的SAPI模式有五種:
CLI和CGI模式(單一進程模式)
多重行程模式
多執行緒模式
#FastCGI模式
嵌入式
1. CLI/CGI模式
CLI和CGI都屬於單一進程模式,PHP的生命週期在一次請求中完成。也就是說每次執行PHP腳本,都會執行第二部分講的四個INT和Shutdown事件。
圖2. CGI/CLI生命週期
2. 多進程模式(Multiprocess)
多重進程模式可以將PHP內建到Web Server中,PHP可以編譯成Apache下的prefork MPM模式和APXS模組,當Apache啟動後,會fork很多子進程,每個子進程都有自己獨立的進程位址空間。
圖3. 多進程模式生命週期
在一個子進程中,PHP的生命週期是呼叫MINT啟動後,執行多次請求(RINT/RSHUTDOWN),在Apache關閉或進程結束後,才會呼叫MSHUTDOWN進行回收階段。
圖4. 多進程的生命週期
多重進程模型中,每個子進程都是獨立運行,沒有程式碼和資料共享,因此一個子進程終止退出和重新生成,不會影響其他子進程的穩定。
3. 多執行緒模式(Multithreaded)
Apache2的Worker MPM採用了多執行緒模型,在一個行程下建立多個執行緒,在同一個行程位址空間執行。
圖5. 多執行緒生命週期
4. FastCGI模式
在我們用的Nginx+PHP-FPM用的就是FastCGI模式,Fastcgi是一種特殊的CGI模式,是一種常駐進程類型的CGI,運行後可以Fork多個進程,不用花時間動態的Fork子進程,也不需要每次請求都呼叫MINT/MSHUTDOWN。 PHP透過PHP-FPM來管理和調度FastCGI的進程池。 Nginx和PHP-FPM透過本地的TCP Socket和Unix Socket 進行通訊。
圖6. FastCGI模式生命週期
PHP-FPM进程管理器自身初始化,启动多个CGI解释器进程等待来自Nginx的请求。当客户端请求达到PHP-FPM,管理器选择到一个CGI进程进行处理,Nginx将CGI环境变量和标准输入发送到一个PHP-CIG子进程。PHP-CGI子进程处理完成后,将标准输出和错误信息返回给Nginx,当PHP-CGI子进程关闭连接时,请求处理完成。PHP-CGI子进程等待着下一个连接。
可以想象CGI的系统开销有多大。每一个Web 请求PHP都必须重新解析php.ini、载入全部扩展并始化全部数据结构。使用FastCGI,所有这些都只在进程启动时发生一次。另外,对于数据库和Memcache的持续连接可以工作。
5. 内嵌模式(Embedded)
Embed SAPI是一种特殊的SAPI,允许在C/C++语言中调用PHP提供的函数。这种SAPI和CLI模式一样,按照Module Init => Request Init => Request => Request Shutdown => Module Shutdown的模式运行。
Embed SAPI可以调用PHP丰富的类库,也可以实现高级玩法,比如可以查看PHP的OPCODE(PHP执行的中间码,Zend引擎的指令,由PHP代码生成)。
详细请见: http://www.laruence.com/2008/09/23/539.html
SAPI的运行机制
我们以CGI为例,看一下SAPI的运行机制。
static sapi_module_struct cgi_sapi_module = { "cgi-fcgi", /* 输出给php_info()使用 */ "CGI/FastCGI", /* pretty name */ php_cgi_startup, /* startup 当SAPI初始化时,首先会调用该函数 */ php_module_shutdown_wrapper, /* shutdown 关闭函数包装器,它用来释放所有的SAPI的数据结构、内存等,调用php_module_shutdown */ sapi_cgi_activate, /* activate 此函数会在每个请求开始时调用,它会做初始化,资源分配 */ sapi_cgi_deactivate, /* deactivate 此函数会在每个请求结束时调用,它用来确保所有的数据都得到释放 */ sapi_cgi_ub_write, /* unbuffered write 不缓存的写操作(unbuffered write),它是用来向SAPI外部输出数据 */ sapi_cgi_flush, /* flush 刷新输出,在CLI模式下通过使用C语言的库函数fflush实现*/ NULL, /* get uid */ sapi_cgi_getenv, /* getenv 根据name查找环境变量 */ php_error, /* error handler 注册错误处理函数 */ NULL, /* header handler PHP调用header()时候被调用 */ sapi_cgi_send_headers, /* send headers handler 发送头部信息*/ NULL, /* send header handler 发送一个单独的头部信息 */ sapi_cgi_read_post, /* read POST data 当请求的方法是POST时,程序获取POST数据,写入$_POST数组 */ sapi_cgi_read_cookies, /* read Cookies 获取Cookie值 */ sapi_cgi_register_variables, /* register server variables 给$_SERVER添加环境变量 */ sapi_cgi_log_message, /* Log message 输出错误信息 */ NULL, /* Get request time */ NULL, /* Child terminate */ STANDARD_SAPI_MODULE_PROPERTIES };
由上面代码可见,PHP的SAPI像是面向对象中基类,SAPI.h和SAPI.c包含的函数是抽象基类的声明和定义,各个服务器用的SAPI模式,则是继承了这个基类,并重新定义基类方法的子类。
总结
PHP的SAPI是Zend引擎提供的一组标准交互接口,通过注册初始化、析构、输入、输出等接口,我们可以将应用程序运行在Zend引擎上,也可以把PHP嵌入到类似Apache的Web Server中。PHP常见的SAPI模式有五种,CGI/CLI模式、多进程模式、多线程模式、FastCGI模式和内嵌模式。
了解PHP的SAPI机制意义重大,帮助我们理解PHP的生命周期,并了解如何更好的通过C/C++为PHP编写扩展,并在生命周期中找到提高系统性能的方式。
相关推荐:
以上是PHP核心SAPI探究實例分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。
