這篇文章,研究一下PHP程式碼是如何解釋和執行以及PHP腳本運行的生命週期。
概述
PHP服務的啟動。嚴格來說,PHP的相關進程是不需要手動啟動的,它是隨著Apache的啟動而運作的。當然,如果有需要重啟PHP服務的情況下也是可以手動重啟PHP服務的。比如說在有開啟opcode的正式環境更新了程式碼之後,就需要重新啟動PHP才能重新編譯PHP程式碼。
從宏觀來看,PHP內核的實現就是接收輸入的數據,內部做相應的處理然後輸出結果。對PHP核心來說,我們寫的PHP程式碼就是核心接收的輸入數據,PHP核心接收程式碼資料後,對我們寫的程式碼進行程式碼解析和運算執行,最後回傳對應的運算結果。
然而,不同於平常的C語言程式碼,要執行PHP程式碼,首先需要將PHP程式碼「翻譯」成機器語言來執行對應的功能。而要執行「翻譯」這個步驟,就需要PHP核心進行:詞法分析、文法分析等步驟。最後交給PHP內核的Zend Engine進行順次的執行。
詞法分析
將PHP代碼分隔成一個個的「單元」(TOKEN)
語法分析
將「單元」轉換為Zend Engine可執行的操作
Zend Engine
對語法分析得到的操作順次的執行
一切PHP程式(CGI/CLI)的開始都是從SAPI(Server Application Programming Interface)介面開始。 SAPI指的是PHP具體應用的程式介面。例如Apache的mod_php。
PHP開始執行以後會經過兩個主要的階段:處理請求之前的開始階段和請求之後的結束階段。
開始階段
PHP的整個開始階段會經歷模組初始化和模組激活兩個階段。
MINIT
即模組初始化階段,發生在Apache/Nginx啟動以後的整個生命週期或命令列程式整個執行過程中,此階段只進行一次
RINIT
模組激活,發生在請求階段。做一些初始化工作:如註冊常數、定義模組使用的類別等等
模組在實作時可以透過如下巨集來實現這些回呼函數:
PHP_MINIT_FUNCTION(myphpextension) { //注册常量或者类等初始化操作 return SUCCESS; } PHP_RINIT_FUNCTION(myphpextension) { //例如记录请求开始时间 //随后在请求结束的时候记录结束时间。这样我们就能够记录处理请求所花费时间了 return SUCCESS; }
PHP腳本請求處理完就進入了結束階段,一般腳本執行到結尾或呼叫exit或die函數,PHP就進入結束階段。
結束階段
PHP的結束階段分為停用模組和關閉模組兩個環節。
RSHUTDOWN
停用模組(對應RINIT)
MSHUTDOWN
關閉模組(對應MINIT)
CLI/CGI模式的PHP屬於單一進程的SAPI模式。意思是說,PHP腳本在執行一次之後就關閉掉,所有的變數和函數都不能繼續使用。即在CGI模式下,同一個php檔案的變數在其他php檔案中不能使用。
下面用一個例子來看看單執行緒PHP的SAPI生命週期。
單執行緒SAPI生命週期
如:
php -f test.php
呼叫各個擴充的MINIT 模組初始化
請求test.php
》 test. 呼叫各個擴充的RSHUTDOWN 停用模組
執行完test.php後清理變數和記憶體
呼叫各個擴充的MSHUTDOWN 關閉模組
停止PHP執行
以上是一個簡單的執行流程,下面做一些補充。
PHP在呼叫每個模組的模組初始化前,會有一個初始化的過程,包括:
初始化若干全域變數 大多數情況下是將其設為NULL。
初始化若干常數
初始化Zend引擎和核心元件
解析php.ini
全域操作函數的初始化
初始化靜態建置的模組和共用模組(MINIT)
模組初始化執行操作:
將模組註冊到已註冊模組列表
將每個模組中包含的函數註冊到函數表
禁用函數和類別
會呼叫zend_disable_function函數將PHP的配置文件中的disable_functionsable_functions變數代表的函數從CG(function_table)函數表中刪除。
啟動Zend引擎
使用init_compiler函數來初始化編譯器。啟動SAPI
使用sapi_activate函數來初始化SG(sapi_headers)和SG(request_info),並且針對HTTP請求的方法設定一些內容。
環境初始化
初始化在使用者控制項需要用到的一些環境變數。包括伺服器環境、請求資料環境等。
模組請求初始化
PHP呼叫zend_activate_modules函數遍歷註冊在module_registry變數中的所有模組,呼叫其RINIT方法方法實現模組的請求初始化操作。
在處理了文件相關的內容後,PHP會呼叫php_request_startup做請求初始化操作:
啟動Zend引擎
啟動SAPI
環境初始化
模組請求初始化
DEACTIVATION(關閉請求)
以上就介紹了PHP是怎麼運作的,包括了方面的內容,希望對PHP教學有興趣的朋友有幫助。
呼叫所有透過register_shutdown_function()註冊的函數。這些在關閉時呼叫的函數是在用戶空間添加進來的。
執行所有可用的__destruct函數。這裡的析構函數包括在物件池(EG(objects_store)中的所有物件的析構函數以及EG(symbol_table)中各個元素的析構方法。
將所有的輸出刷出去。
發送HTTP應答頭。
銷毀全域變數表(PG(http_globals))的變數。
透過zend_deactivate函數,關閉詞法分析器、語法分析器和中間程式碼執行器。函數指標都是NULL。
結束
PHP結束一個進程是,會呼叫sapi_flush函數將最後的內容刷新出去。 (http://www.php-internals.com/book/)

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

方法:1、用“str_replace(" ","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\ \;||\xc2\xa0)/","其他字符",$str)”语句。

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

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

Atom編輯器mac版下載
最受歡迎的的開源編輯器

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

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

Dreamweaver Mac版
視覺化網頁開發工具