您好,欢迎访问一九零五行业门户网

PHP7 源码整体框架详解

推荐(免费):php7
一、php7语言执行原理
常用的高级语言有很多种,根据运行的方式不同,大体分为两种:编译型语言和解释型语言。
编译是指在应用源程序执行之前,就将程序源代码“翻译”成汇编语言,然后进一步根据软硬件环境编译成目标文件。一般称完成编译工作的工具为编译器。
而解释型语言,在程序运行时才被“翻译”为机器语言。但是执行一次“翻译”一次,所以执行效率较低。解释器的工作就是解释型语言中,负责“翻译”源代码的程序。
对于一段c语言代码,需要经过预编译、编译、汇编和链接,才能成为可执行的二进制文件。
以c语言为代表的编译型语言,代码发生更新都要经过以上步骤。
编译型语言的执行示意:
对编译型语言与解释型语言的区别的理解,立足于源代码被编译成目标平台cpu指令的时机。对于编译型语言,编译结果已经是针对当前cpu体系的指令;而解释型语言,需要先编译成中间代码,再经由该解释型语言的特定虚拟机,翻译成特定cpu体系的指令被执行。解释型语言是在运行过程中,翻译为目标平台的指令。常说解释型语言“慢”,主要也是慢在这里。
在php 7中,源代码首先进行词法分析,将源代码切割为多个字符串单元,分割后的字符串称为token。而一个一个独立的token是无法表达完整语义的,需经过语法分析阶段,将token转换为抽象语法树(简称ast)。之后,抽象语法树被转换为机器指令执行。在php中,这些指令称为opcode。
第1步:源码通过词法分析得到token。
第2步:基于语法分析器生成抽象语法树(ast)。
第3步:抽象语法树转换为opcodes(opcode指令集合),php解释执行opcodes。
1.token
token是php代码被切割成的有意义的标识。php提供了token_get_all()函数来获取php代码被切割后的token.。
二维数组的每个成员数组的第一个值为token对应的枚举值。第二个值为token对应的原始字符串内容。第三个值为代码对应的行号。
可见,token就是一个个的“词块”,但是单独存在的词块不能表达完整的语义,还需要借助规则进行组织串联。语法分析器就是这个组织者。它会检查语法,匹配token,对token进行关联。
2.ast
ast是php 7版本新特性。在这之前的版本中,php代码的执行过程中是没有生成ast这一步的。
ast的节点分为多种类型,对应着php语法。
php-parser工具,它可以用来查看php代码生成的ast。
注意 php-parser是php 7内核作者之一nikic编写的将php源码生成ast的工具。源码见https://github.com/nikic/php-parser。
3.opcodes
opcode只是单条指令,opcodes是opcode的集合形式,是php执行过程中的中间代码。opcode生成之后由虚拟机执行。
php工程优化措施中有一个比较常见的“开启opcache”,指的就是这里的opcodes的缓存(opcodes cache)。通过省去从源码到opcode的阶段,引擎可以直接执行缓存的opcode,以此
提升性能。
借助vld插件,可以直观地看到一段php代码生成的opcode。
opcode是php 7定义的一组指令标识,指令对应着相应的handler(处理函数)。当虚拟机调用opcode,会找到opcode背后的处理函数,执行真正的处理。
二、内核架构
zend引擎中包含了编译器和解释器,从php代码到opcode的执行,均由zend引擎完成。
zend引擎除了实现了php的核心功能,还提供了一套接口,让php可以在更多的场景中使用,如命令行环境、web环境等。
该架构图大致分为四大部分。
1)zend引擎:前文介绍的词法/语法分析、ast编译和opcodes的执行均在zend引擎中实现。此外,php的变量设计、内存管理、进程管理等也在引擎层实现。引擎为php提供了基础服务,php的可靠性和高性能都依赖引擎的基础支撑。同时,zend引擎的可扩展性,还是php得以大规模应用的重要原因之一。
2)php层:zend引擎为php提供基础能力(如内存分配和回收),而来自外部的交互则需要通过php层来处理。
3)sapi:sapi是server api的缩写,其中包含了常见的cli sapi和fpm sapi。php定义好输入/输出规范,依据此规范与php交互的一方都可以称为server。
4)扩展部分:zend引擎提供了核心能力和接口规范。在此基础上开发的扩展,为php代码的性能和功能的多样性提供了更丰富的选项。
三、php源码目录
sapi目录源码
sapi目录是对输入和输出层的抽象,是php提供对外服务的规范。
php程序的输入可以是来自于命令行的标准输入,也可以是来自基于cgi/fastcgi协议的网络请求。同理,输出可以写到命令行的标准输出,也可以作为基于cgi/fastcgi协议的网络响应返回给客户端。
命令行模式对应的是二进制程序bin/php;内置模块的模式不需要提供二进制程序,作为普通函数供apache或任意c/c++程序来调用即可;cgi模式对应的是二进制程序bin/cgi;fastcgi模式对应的是二进制程序sbin/php-fpm。
几种常用的sapi。
1)apache2handler:apache扩展,编译后生成动态链接库,配置到apache下,当有http请求到apache时,根据配置会调用此动态链接库,执行php代码,完成与php的交互。
2)cgi-fcgi:编译后生成支持cgi协议的可执行程序,webserver(通常为apache或nginx)通过cgi协议把请求传给cgi进程,执行代码将结果返回给webserver,退出进程。
3)fpm-fcgi:fpm全称为fastcgi process manager,php官方提供的fastcgi进程管理器。以nginx服务器为例,当有http协议请求发送到nginx服务器,nginx按照fastcgi协议把请求交给php-fpm进程处理。
4)cli:command line interface的简称,php的命令行交互接口。
zend目录源码
zend目录是php的核心代码。
1.内存管理模块
2.垃圾回收
3.数组实现
main目录源码
main目录是sapi层和zend层的黏合剂。
zend层实现了php脚本的编译和执行,sapi层实现了输入和输出的抽象,main目录则起到了承上启下的作用:承上,解析sapi的请求,分析要执行的脚本文件和参数;启下,调用zend引擎之前,完成必要的初始化等工作。
ext目录源码
ext是php扩展相关的目录,常用的array、str、pdo等系列函数都在这里定义。
tsrm目录源码
php在早期更多的是单个进程、单线程模型运行的,在后期才引入了线程安全机制zts(zend thread safety)。
tsrm是thread safe resource manager的缩写——线程安全资源管理器。
线程安全机制主要为了保证共享资源的安全。php的线程安全机制简洁直观——在多线程环境下,为每个线程提供独立的全局变量副本。具体实施是通过tsrm为每个线程分配(分配前加锁)一个独立id(自增)作为当前线程的全局变量内存区索引,在以后的全局变量访问中,实现线程之间的完全独立。
以上就是php7 源码整体框架详解的详细内容。
其它类似信息

推荐信息