PHP 解释器是个 C 程序。
它是解释型语言,所以无需编译,但这个编译指的是『编译成二进制文件』。
但是从脚本到结果,中间还是有一系列过程的。
语言本身只是为了更符合人的习惯,PHP 解释器最终执行的是 opcode。
从从 php 脚本到 opcodes 的的过程在 PHP5 中是:
Lexing:词法扫描分析,将源文件转换成 token 流;
Parsing:语法分析,在此阶段生成 op arrays。
PHP7 中在语法分析阶段不再直接生成 op arrays,而是先生成 AST,所以过程多了一步:
Lexing:词法扫描分析,将源文件转换成 token 流;
Parsing:语法分析,从 token 流生成抽象语法树;
Compilation:从抽象语法树生成 op arrays。
上面的 lexing,也就是词法分析,PHP 用的是 re2c,parsing 也就是语法分析,PHP 用的是bison。
lexing 做一些符号替换,状态记录的东西。
parsing 会去扫描语法,然后调用相应的处理函数,比如 zend_do_begin_class_declaration 之类的函数。当然这是 PHP5,PHP7 它会先去调 zend_ast_create 之类的。
接下来 PHP5 中 parsing 调的相应的处理函数就会将语句转换成 opcode,将变量存在内存中,函数名、类名存在符号表中。
PHP7 中会有 compile 相关的函数去分析抽象语法树,然后得到和上面相同的结果。
这样你的变量、类、函数都在内存中准备就绪了,你的赋值语句、函数调用语句都已经变成了顺序排列的一条一条的 opcode array了。
然后就是执行了。会有一个 excute 相关的函数来一条一条的执行 opcode,得到的就是你要的结果。
所以你的类虽然写在下面,但是完全可以被找到的。
上面说的这些过程,对应的 PHP 解释器中的文件分别是:
zend_language_scanner.l
zend_language_parser.y
zend_ast.c (PHP7)
zend_compile.c
zend_excute.c
如果有 C 语言的底子,尝试从另外一个层面去了解会更简单。