脚本执行:
在前面的章节介绍了PHP的生命周期,PHP的SAPI,SAPI处于整个架构较上层,而真正的执行主要由Zend引擎来完成,这一小节我们介绍PHP脚本的执行。
目前编程语言可以分为两大类:
第一类:像C/C++,.NET,Java之类的编译型语言,它们的共性是:运行之前必须对源代码进行编译,然后运行编译后的目标文件。
第二类:比如PHP,javascript,Ruby,Python这些解释型语言,他们都无需经过编译即可“运行”,虽然可以理解为直接运行,但是他们并不是直接真的直接就被机器理解,机器智能理解机器语言,那这些语言是怎么被执行的呢,一般这些语言都需要一个解释器,由解释器来执行这些源码,实际上这些语言还是会经过编译环节,只不过它们一般会在运行的时候实时进行编译。为了效率,并不是所有语言在每次执行的时候都会重新编译一遍,比如PHP的各种opcode缓存扩展(如APC,Xcache,eAccelerator等),比如Python会将编译的中间文件保存成pyc/pyo文件,避免每次运行重新编译所带来的性能损失。
用具体的例子来展示一下PHP脚本的执行:
hello.php文件里面的代码如下:
$str = "Hello World";
echo $str;
通过cli命令行执行如下程序:
$ php ./hello.php
整体的程序执行:
1 如上例中,传递给php程序需要执行的文件,php程序完成基本的准备工作后启动PHP及Zend引擎,加载注册的扩展模块。
2 初始化完成后读取脚本文件,Zend引擎对脚本文件进行词法分析、语法分析、然后编译成opcode执行。如果安装了apc之类的opcode缓存,编译环境可能会被跳过而直接从缓存中读取opcode执行。
脚本的编译执行
_______________________________________________________________________________
PHP在读取到脚本文件后首先对代码进行词法分析,PHP的词法分析器是通过lex生成的,词法规则文件在$PHP_SRC/Zend/zend_language_scanner.l,这一阶段lex会将源代码按词法规则切分一个一个的标记(token).PHP提供了一个函数token_get_all(),该函数接收一个字符串参数,返回一个按照词法规则切分好的数组。
Zend引擎词法分析器做的事情,就是将代码切分为一个个的标记。
然后使用语法分析器(PHP使用bison生成语法分析器,规则见$PHP_SRC/Zend/zend_language_parser.y),bison根据规则进行相应的处理,如果代码找不到匹配的规则,也就是语法错误时Zend引擎会停止,并输出错误信息。
php初学者---千锋php课堂笔记