octobercms 执行php代码_PHP7语言执行原理

常用的高级语言有很多种,根据运行的方式不同,大体分为两种:编译型语言和解释型语言。

编译是指在应用源程序执行之前,就将程序源代码“翻译”成汇编语言,然后进一步根据软硬件环境编译成目标文件。一般称完成编译工作的工具为编译器

而解释型语言,在程序运行时才被“翻译”为机器语言。但是执行一次“翻译”一次,所以执行效率较低。解释器的工作就是解释型语言中,负责“翻译”源代码的程序。

对于一段C语言代码,需要经过预编译、编译、汇编和链接,才能成为可执行的二进制文件。

以C语言为代表的编译型语言,代码发生更新都要经过以上步骤。

编译型语言的执行示意:

974651c4bbf33873ef08ab014c2ed8f3.png

对编译型语言与解释型语言的区别的理解,立足于源代码被编译成目标平台CPU指令的时机。对于编译型语言,编译结果已经是针对当前CPU体系的指令;而解释型语言,需要先编译成中间代码,再经由该解释型语言的特定虚拟机,翻译成特定CPU体系的指令被执行。解释型语言是在运行过程中,翻译为目标平台的指令。常说解释型语言“慢”,主要也是慢在这里。

在PHP 7中,源代码首先进行词法分析,将源代码切割为多个字符串单元,分割后的字符串称为Token。而一个一个独立的Token是无法表达完整语义的,需经过语法分析阶段,将Token转换为抽象语法树(简称AST)。之后,抽象语法树被转换为机器指令执行。在PHP中,这些指令称为opcode。

d30d4e1c5db04cce9e77418327a0deba.png

第1步:源码通过词法分析得到Token。
第2步:基于语法分析器生成抽象语法树(AST)。
第3步:抽象语法树转换为opcodes(opcode指令集合),PHP解释执行opcodes。

e801c4e6879508c838f699ddc7b74e57.png


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环境等。

b10166ea39d949e0dddcc27eba7e48d5.png


该架构图大致分为四大部分。
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(自增)作为当前线程的全局变量内存区索引,在以后的全局变量访问中,实现线程之间的完全独立。

以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要请戳这里链接 或者 知乎专栏
PHP7进阶架构师​zhuanlan.zhihu.com
295e50ee53e925d2c1077784797c2ca1.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/529139.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一般程序句柄多少linux,一个进程能够打开最大文件句柄数设到多大才合适(Linux)...

命令可以看到单个进程能够打开的最大文件句柄数量(socket连接也算在里面)。系统默认值1024。对于一般的应用来说(象Apache、系统进程)1024完全足够使用。但是如何象squid、mysql、java等单进程处理大量请求的应用来说就有点捉襟见肘了。如果单个进程打开的文件句柄数量超过了系…

convert.todatetime指定日期格式_JDK1.8新增日期时间类型

如果我们可以跟别人说:“我们在1502643933071见面,别晚了!”那么就再简单不过了。但是我们希望时间与昼夜和四季有关,于是事情就变复杂了。Java1.0中包含了一个Date类,但是它的大多数方法已经在Java 1.1引入Calendar类…

linux shell运行脚本命令行参数,shell脚本命令行参数简介

之所以用到命令行参数,关键在于shell脚本需要与运行脚本的人员进行交互。bash shell提供了命令行参数添加在命令后面的数据值)、命令行选项修改命令行为的单字符值)和直接读取键盘输入。1、命令行参数向shell脚本传递数据的最基本方式是使用命令行参数。1)读取参数读…

eclipse linux远程调试工具,使用本地Eclipse IDE调试器与远程项目源(Linux)

我试图找出以下情况的最佳方法。我有几个Java源文件正在使用JNI与一些C源代码进行通信,这些源代码都驻留在Linux机器上。 Java部分在Linux机器上完美地构建和运行(通过JUnit)。 Java类依赖于几个Linux(.so)库。我想在本地计算机(Mac OS X)上运行Eclipse IDE调试器&a…

python下载文件的第三方库_Python常用第三方库(转载)

wxPython 如果你之前是 windows 程序员,用 MFC 或者 WIN32API 开发界面程序,那进入 Python 国度最好的 GUI 选择应该是 wxPython。它是 wxWidgets 的 Python Bind,与 wxWidgets 的开发完美同步,最为重要的一点是它的消息机制与 MF…

linux sybase 自动备份,Linux平台下Sybase数据库备份方法分析.doc

Linux平台下Sybase数据库备份方法分析Linux平台下Sybase数据库备份方法分析摘 要:对于从事信息系统管理的人员来说,掌握数据库的备份方法在工作中尤为重要。当本地数据出错或者磁盘损坏时,可以利用备份的数据恢复数据库系统,从而保…

facebook对话链接_如何应用防错原则,看看 Facebook 和 Gmail 是怎么做的

欢迎来到有言有料,让思考更有张力本文共 3873 字,预计阅读 10 分钟作者|Siddharth Gulati译者|张聿彤本文翻译已获得作者的正式授权(授权截图如下)在用户界面(UI)设计中,重要的是要注意最细微的细节,以使用…

linux 7 定时任务设置,centos7 配置crontab定时任务

1. 启动cron服务# 查看服务状态systemctl status crond# 启动systemctl start crond# 停止systemctl stop crond# 重启systemctl restart crond# 重新加载systemctl reload crond2. 开机自动启动cron服务systemctl start crond.service3. 通过crontab命令管理定时任务crontab命…

模拟灰度传感器循迹的程序_PLC编程,实例讲解西门子PLC模拟量编程

给大伙分享的是关于西门子S7-300PLC模拟量方面的实例,包含了以下几个方面的要点:1、对变送器进行取值,并进行控制2、对模数功能块 FC105 进行调用3、对 AI 模块进行设置4、对 AI 量程块进行选择这个实例, 调试的是一个流量调节回路…

linux mint 17 输入法,LinuxMint17.1 Rebecca中安装设置输入法

LinuxMint14使用了几年一直未更新,突然想去更新一下去发现源已经不支持了,所以就直接安装了最新版本。安装好以后发现还是跟以前一样的毛病,没有中文输入法,直接sudo aptitude install fcitx* 发现仍然不行。运行im-config设定FCI…

python组成不重复的三位数是多少_Python输出由1,2,3,4组成的互不相同且无重复的三位数...

题目:有四个数字:1、2、3、4,能组成多少个互不相同且无重复数字的三位数?各是多少? 程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去 掉不满足条件的排列。 程序源代码 方法1&…

作业调度C语言编写,【作业调度方案】 (C语言代码)

解题思路:如图所示,对于第一组样例输入,按照总工序提供的顺序,对于每个工件的工序从小到大,每次寻找有空闲机器的“空档”插入,就能让总加工时间最短。注意事项:按照约定,最短方案有且只有一种。参考代码:#…

python判断能否组成三角形_python三角形判定怎么做

python三角形判定怎么做?下面给大家带来具体的例子: 相关推荐:《Python视频教程》 例子:a int(input("The length of the side a ")) b int(input("The length of the side b ")) c int(input("The…

文件的记录c语言程序,c语言程序学生籍贯信息记录簿设计.docx

c 语言程序学生籍贯信息记录簿设计学生籍贯信息记录簿课程设计报告书班 级: 方 0909-1 学 号:姓 名: 苑 小 叶 指导教师 : 康 亚 男 石家庄铁道大学四方学院2010年 07月 14日1课程设计报告内容1. 选择题目题目: 学生籍贯信息记录簿设计 2. 内容摘要摘要:学生籍贯信息管理系统是…

如何修改linux的java路径_修改桌面文件默认存储位置的正确方式及注意事项

之前写了篇关于如何修改桌面文件默认存储位置,许多人在修改后出现各种问题,今天重新来讲解一下关于修改桌面文件默认存储位置的正确方式及注意事项。第一步、在E盘下创建一个文件夹,随便取个名字,或者默认为【新建文件夹】&#x…

secp256r1 c语言程序,rust代码阅读 之 libsecp256k1 (1)

在密码学的运算中, 数字通常是非常大的. 以 ECDSA 椭圆曲线为例, 私钥是 256 位的.所以在 libsecp256k1 这个库里, 定义了计算的元素 Field. 其中 n 为 320 位.pub struct Field {pub(crate) n: [u32; 10],pub(crate) magnitude: u32,pub(crate) normalized: bool,}为其实现加法…

python位运算符_详细介绍Python语言中的按位运算符

按位运算符是把数字看作二进制来进行计算的。Python中的按位运算法则如下: 按位与 ( bitwise and of x and y ) & 举例: 5&3 1 解释: 101 11 相同位仅为个位1 ,故结果为 1 按位或 ( bitwise or of x and y ) | 举例&…

c语言代码测试电脑性能,【图片】今天写几个性能测试,为什么C语言跑得这么慢呢??【c语言吧】_百度贴吧...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼易言版本……跑100000万成绩不如PHP。。。。.版本 2.程序集 程序集1.子程序 _启动子程序, 整数型, , 本子程序在程序启动后最先执行.局部变量 参数, 文本型, , "0".局部变量 to, 整数型.局部变量 fr, 整数型.局部变量 n,…

python find函数 和index的区别_使用带有find和index的map时Python2和Python3之间的区别...

给定一个模式和一个字符串str,找到str是否遵循相同的模式. 以下是完全匹配,使得在模式中的字母和str中的非空字之间存在双射. 例子: pattern “abba”,str “dog cat cat dog”应该返回true;狗是一只猫,猫是b,而这些词形成了abba模式. pattern “abba”,str “dog c…

c语言3368题目,电大《C语言程序设计课程》期末考试复习资料

0993C 评议程序设计A 第 1 页 共 31 页C 语言程序设计课程期末复习练习一、单选题 1.在每个C 语言程序中都必须包含有这样一个函数,该函数的函数名为( )。A. main 2.每个C 语言程序文件的编译错误分为( )类。B. 2 3. 字符串"ab12\n"…