腳本執(zhí)行:
在前面的章節(jié)介紹了PHP的生命周期盏浙,PHP的SAPI,SAPI處于整個(gè)架構(gòu)較上層貌虾,而真正的執(zhí)行主要由Zend引擎來(lái)完成,這一小節(jié)我們介紹PHP腳本的執(zhí)行啼染。
目前編程語(yǔ)言可以分為兩大類:
第一類:像C/C++琢岩,.NET,Java之類的編譯型語(yǔ)言,它們的共性是:運(yùn)行之前必須對(duì)源代碼進(jìn)行編譯师脂,然后運(yùn)行編譯后的目標(biāo)文件担孔。
第二類:比如PHP,javascript,Ruby,Python這些解釋型語(yǔ)言江锨,他們都無(wú)需經(jīng)過(guò)編譯即可“運(yùn)行”,雖然可以理解為直接運(yùn)行糕篇,但是他們并不是直接真的直接就被機(jī)器理解啄育,機(jī)器智能理解機(jī)器語(yǔ)言,那這些語(yǔ)言是怎么被執(zhí)行的呢拌消,一般這些語(yǔ)言都需要一個(gè)解釋器挑豌,由解釋器來(lái)執(zhí)行這些源碼,實(shí)際上這些語(yǔ)言還是會(huì)經(jīng)過(guò)編譯環(huán)節(jié)墩崩,只不過(guò)它們一般會(huì)在運(yùn)行的時(shí)候?qū)崟r(shí)進(jìn)行編譯氓英。為了效率,并不是所有語(yǔ)言在每次執(zhí)行的時(shí)候都會(huì)重新編譯一遍鹦筹,比如PHP的各種opcode緩存擴(kuò)展(如APC,Xcache,eAccelerator等)铝阐,比如Python會(huì)將編譯的中間文件保存成pyc/pyo文件,避免每次運(yùn)行重新編譯所帶來(lái)的性能損失铐拐。
用具體的例子來(lái)展示一下PHP腳本的執(zhí)行:
hello.php文件里面的代碼如下:
$str = "Hello World";
echo $str;
通過(guò)cli命令行執(zhí)行如下程序:
$ php ./hello.php
整體的程序執(zhí)行:
1 如上例中徘键,傳遞給php程序需要執(zhí)行的文件,php程序完成基本的準(zhǔn)備工作后啟動(dòng)PHP及Zend引擎遍蟋,加載注冊(cè)的擴(kuò)展模塊吹害。
2 初始化完成后讀取腳本文件,Zend引擎對(duì)腳本文件進(jìn)行詞法分析虚青、語(yǔ)法分析它呀、然后編譯成opcode執(zhí)行。如果安裝了apc之類的opcode緩存挟憔,編譯環(huán)境可能會(huì)被跳過(guò)而直接從緩存中讀取opcode執(zhí)行钟些。
腳本的編譯執(zhí)行
_______________________________________________________________________________
PHP在讀取到腳本文件后首先對(duì)代碼進(jìn)行詞法分析,PHP的詞法分析器是通過(guò)lex生成的绊谭,詞法規(guī)則文件在$PHP_SRC/Zend/zend_language_scanner.l,這一階段lex會(huì)將源代碼按詞法規(guī)則切分一個(gè)一個(gè)的標(biāo)記(token).PHP提供了一個(gè)函數(shù)token_get_all(),該函數(shù)接收一個(gè)字符串參數(shù)政恍,返回一個(gè)按照詞法規(guī)則切分好的數(shù)組。
Zend引擎詞法分析器做的事情达传,就是將代碼切分為一個(gè)個(gè)的標(biāo)記篙耗。
然后使用語(yǔ)法分析器(PHP使用bison生成語(yǔ)法分析器,規(guī)則見(jiàn)$PHP_SRC/Zend/zend_language_parser.y),bison根據(jù)規(guī)則進(jìn)行相應(yīng)的處理宪赶,如果代碼找不到匹配的規(guī)則宗弯,也就是語(yǔ)法錯(cuò)誤時(shí)Zend引擎會(huì)停止,并輸出錯(cuò)誤信息搂妻。
php初學(xué)者---千鋒php課堂筆記