![](https://img-blog.csdnimg.cn/20201014180756925.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
php底层探究
文章平均质量分 60
行善积德韩老魔
我们很容易觉得科技的核心就是技术本身.
这是不对的,你我才是核心.
展开
-
一、PHP内核探索:从SAPI接口开始 - Zend SAPI Internals
SAPI:Server Application Programming Interface 服务器端应用编程端口。研究过PHP架构的同学应该知道这个东东的重要性,它提供了一个接口,使得PHP可以和其他应用进行交互数据。 本文不会详细介绍每个PHP的SAPI,只是针对最简单的CGI SAPI,来说明SAPI的机制。我们先来看看PHP的架构图:SAPI指的是PHP具体应用的编程接口, 就像...原创 2019-08-27 17:49:13 · 263 阅读 · 0 评论 -
二、PHP内核探索:一次请求的开始与结束 - MINIT与RINIT
PHP开始执行以后会经过两个主要的阶段:处理请求之前的开始阶段 请求之后的结束阶段开始阶段有两个过程:第一个过程是模块初始化阶段(MINIT), 在整个SAPI生命周期内(例如Apache启动以后的整个生命周期内或者命令行程序整个执行过程中), 该过程只进行一次。第二个过程是模块激活阶段(RINIT),该过程发生在请求阶段, 例如通过url请求某个页面,则在每次请求之前都会进行模块...原创 2019-08-27 17:49:49 · 551 阅读 · 0 评论 -
三、PHP内核探索:一次请求生命周期 - PHP的启动与关闭
我们从未手动开启过PHP的相关进程,它是随着Apache的启动而运行的。PHP通过mod_php5.so模块和Apache相连(具体说来是SAPI,即服务器应用程序编程接口)。PHP总共有三个模块:内核、Zend引擎、以及扩展层。PHP内核用来处理请求、文件流、错误处理等相关操作; Zend引擎(ZE)用以将源文件转换成机器语言,然后在虚拟机上运行它; 扩展层是一组函数、类库和流,PH...原创 2019-08-27 17:50:48 · 173 阅读 · 0 评论 -
四、PHP内核探索:单进程SAPI生命周期 - 处理一次请求后就关闭
CLI/CGI模式的PHP属于单进程的SAPI模式。这类的请求在处理一次请求后就关闭。也就是只会经过如下几个环节: 开始 - 请求开始 - 请求关闭 - 结束 SAPI接口实现就完成了其生命周期。 单进程多请求则如下图所示: ...原创 2019-08-27 17:51:39 · 138 阅读 · 0 评论 -
五、PHP内核探索:多进程/线程的SAPI生命周期 ☞ 重复请求开始-请求关闭的环节
多进程的SAPI生命周期通常PHP是编译为apache的一个模块来处理PHP请求。Apache一般会采用多进程模式, Apache启动后会fork出多个子进程,每个进程的内存空间独立,每个子进程都会经过开始和结束环节, 不过每个进程的开始阶段只在进程fork出来以来后进行,在整个进程的生命周期内可能会处理多个请求。 只有在Apache关闭或者进程被结束之后才会进行关闭阶段,在这两个阶段之间会随着...原创 2019-08-27 17:53:48 · 115 阅读 · 0 评论 -
六、PHP内核探索:Zend引擎 ☞ Zend引擎是PHP实现的核心
相信很多人都听说过 Zend Engine 这个名词,也有很多人知道 Zend Engine 就是 PHP 语言的核心,但若要问一句:Zend Engine 到底存在于何处?或者说,Zend Engine 究竟是在什么时候怎么发挥作用让 PHP 源码输出我们想要的东西的?Zend引擎是PHP实现的核心,提供了语言实现上的基础设施。例如:PHP的语法实现,脚本的编译运行环境, 扩展机制以及内存管...原创 2019-08-27 17:56:15 · 172 阅读 · 0 评论 -
七、PHP内核探索:再次探讨SAPI ☞ 很多操作都是通过SAPI接口实现
在PHP的生命周期的各个阶段,一些与服务相关的操作都是通过SAPI接口实现。 这些内置实现的物理位置在PHP源码的SAPI目录。这个目录存放了PHP对各个服务器抽象层的代码, 例如命令行程序的实现,Apache的mod_php模块实现以及fastcgi的实现等等。在各个服务器抽象层之间遵守着相同的约定,这里我们称之为SAPI接口。 每个SAPI实现都是一个_sapi_module_struct...原创 2019-08-28 09:23:04 · 170 阅读 · 0 评论 -
八、PHP内核探索:Apache模块介绍 ☞ PHP与Apache
Apache概述Apache是目前世界上使用最为广泛的一种Web Server,它以跨平台、高效和稳定而闻名。按照去年官方统计的数据,Apache服务器的装机量占该市场60%以上的份额。尤其是在X(Unix/Linux)平台上,Apache是最常见的选择。其它的Web Server产品,比如IIS,只能运行在Windows平台上,是基于微软.Net架构技术的不二选择。Apache支持许多特...原创 2019-08-28 09:24:27 · 192 阅读 · 0 评论 -
九、PHP内核探索:通过mod_php5支持PHP ☞ Apache2的mod_php5模块说明
Apache对PHP的支持是通过Apache的模块mod_php5来支持的。如果希望Apache支持PHP的话,在./configure步骤需要指定--with-apxs2=/usr/local/apache2/bin/apxs表示告诉编译器通过Apache的mod_php5/apxs来提供对PHP5的解析。在最后一步make install的时候我们会看到将动态链接库libphp5.so(...原创 2019-08-28 09:25:49 · 248 阅读 · 0 评论 -
十、PHP内核探索:Apache运行与钩子函数 ☞ Apache的运行过程
Apache是目前世界上使用最为广泛的一种Web Server,它以跨平台、高效和稳定而闻名。按照去年官方统计的数据,Apache服务器的装机量占该市场60%以上的份额。尤其是在X(Unix/Linux)平台上,Apache是最常见的选择。其它的Web Server产品,比如IIS,只能运行在Windows平台上,是基于微软.Net架构技术的不二选择。Apache并不是没有缺点,它最为诟病的一...原创 2019-08-28 09:26:55 · 149 阅读 · 0 评论 -
十一、PHP内核探索:嵌入式PHP ☞ 嵌入式PHP类似CLI
从PHP源码目录结构的介绍以及PHP生命周期可知:嵌入式PHP类似CLI,也是SAPI接口的另一种实现。 一般情况下,它的一个请求的生命周期也会和其它的SAPI一样:模块初始化=>请求初始化=>处理请求=>关闭请求=>关闭模块。 当然,这只是理想情况。因为特定的应用由自己特殊的需求,只是在处理PHP脚本这个环节基本一致。对于嵌入式PHP或许我们了解比较少,或者说根本用不...原创 2019-08-28 09:29:52 · 176 阅读 · 0 评论 -
十二、PHP内核探索:PHP的FastCGI ☞ FastCGI的整个工作流程
CGI全称是“通用网关接口”(Common Gateway Interface), 它可以让一个客户端,从网页浏览器向执行在Web服务器上的程序请求数据。 CGI描述了客户端和这个程序之间传输数据的一种标准。 CGI的一个目的是要独立于任何语言的,所以CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。 如php,perl,tcl等。FastCGI是Web服务器和处理程序之...原创 2019-08-28 09:30:45 · 153 阅读 · 0 评论 -
十三、PHP内核探索:如何执行PHP脚本 ☞ Zend引擎是如何解释PHP脚本的
前面介绍了PHP的生命周期,PHP的SAPI,SAPI处于PHP整个架构较上层,而真正脚本的执行主要由Zend引擎来完成, 这一小节我们介绍PHP脚本的执行。目前编程语言可以分为两大类:第一类是像C/C++, .NET, Java之类的编译型语言, 它们的共性是:运行之前必须对源代码进行编译,然后运行编译后的目标文件。 第二类比如PHP, Javascript, Ruby, Python...原创 2019-08-28 09:31:50 · 144 阅读 · 0 评论 -
十四、PHP内核探索:PHP脚本的执行细节 ☞ PHP-C-汇编-机器码
众所周知,计算机的CPU只能执行二进制的机器码,每种CPU都有对应的汇编语言,汇编语言编译器将汇编语言翻译成二进制的机器语言,然后CPU开始执行这些机器码。汇编语言作为机器语言与程序设计者之间的一个层,给我们带来了很多方便,程序员不需要用晦涩的01数字来书写程序,当然人们并不满足这样的一个进步,于是在汇编语言之上又多了一个层——C语言,C语言更贴近人类熟悉的“自然语言”,程序设计者可以通过C语言编...原创 2019-08-28 09:32:44 · 175 阅读 · 0 评论 -
十五、PHP内核探索:操作码OpCode ☞ 计算机最终是执行这些OpCode
运行一段PHP代码主要有两个阶段:编译和执行。 当然编译过程中还包括词法分析语法分析不同阶段和细节,这里我们将其作为一个整体。在这两个阶段之间,PHP代码会被编译成op code,可以将其认为是引擎的一个中间语言,编辑阶段把PHP源码生成op code,然后在执行阶段执行这些op code。这篇文章将简单的介绍op code。PHP代码编译之后会生成许多的op,每一个op都是一个zend_op...原创 2019-08-28 09:33:59 · 179 阅读 · 0 评论 -
十六、PHP内核探索:PHP里的opcode ☞ PHP的opcode就是Zend虚拟机中的指令
opcode是计算机指令中的一部分,用于指定要执行的操作, 指令的格式和规范由处理器的指令规范指定。 除了指令本身以外通常还有指令所需要的操作数,可能有的指令不需要显式的操作数。 这些操作数可能是寄存器中的值,堆栈中的值,某块内存的值或者IO端口中的值等等。通常opcode还有另一种称谓:字节码(byte codes)。 例如Java虚拟机(JVM),.NET的通用中间语言(CIL: Comm...原创 2019-08-28 09:35:36 · 180 阅读 · 0 评论 -
PHP未来之路
这门语言现在到底处于生命周期的哪个阶段?其定位到底是怎样的?诸如 PHP7、Swoole 的出现到底能给 PHP 带来怎样的变化?当我们拿 PHP 和 java 进行比较的时候,我们往往就两门语言本身进行比较,如一个是弱类型一个是强类型,一个是数组打天下一个是各种数据结构,甚至连花括号是不是换行写都会被讨论一番。但它们真正的区别并非这些。当我们谈论一门语言的时候,我们是在谈它的生态。“生态”一词在百度百科上的解释是:“生态一词,现在通常是指生物的生活状态。指生物在一定的自然环境下生存和发展的状态原创 2021-06-01 15:08:34 · 505 阅读 · 3 评论 -
php如何判断0和空
函数对0的判断 1 2 3 4 5 $cast_id = 0; var_dump(strlen($cast_id)); //1 var_dump(empty($cast_id)); // true var_dump(isset($cast_id)); //true var_dump(is_null($cast_id));//false 对空的判断 1 2 3 4原创 2021-05-26 15:37:08 · 2598 阅读 · 0 评论 -
运算符 |=、&=、^=
|=关于 |= 运算符:|= 运算符和 += 这一类的运算符一样,拆解开就是 a = a | b;代码如下:public static strictfp void main(String[] args) { int a = 5; // 0000 0101 int b = 3; // 0000 0011 a |= b; // 0000 00111 System.out.println(a);}具体规则为:两个二进制对应位为0时该位为0,否则为1。拿5的二..原创 2021-05-13 14:54:16 · 9757 阅读 · 0 评论 -
I/O 是什么意思?
IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。比如你打开浏览器,访问新浪首页,浏览器这个程序就需要通过网络IO获取新浪的网页。浏览器首先会发送数据给新浪服务器,告诉它我想要首页的HTML,这个动作是往外发数据,叫Output,随后新浪服务器把网页发过来,这个动作是从外面接收数据,叫Input。所以,通常,程序完成IO操作会有Input和Output两个数据流。当然原创 2020-09-01 15:46:54 · 8598 阅读 · 0 评论 -
linux执行rm -rf /*命令后的效果原来是这样
如果你接触过linux,肯定没少听过rm -rf的故事,这个恐怖的命令执行后到底会产生什么样的效果呢?接下来就带大家在虚拟机中演示一下。注意:::一定不能在生产环境中执行此命令,否则没有后悔药可买的!【演示环境】虚拟机:vmware系统:centos用户:root1、执行删除命令前,系统运行良好,且操作正常,如下图所示:2、执行“rm -rf...原创 2019-11-07 16:00:00 · 4125 阅读 · 0 评论 -
PHP内核探索:哈希碰撞攻击是什么?
最近哈希表碰撞攻击(Hashtable collisions as DOS attack)的话题不断被提起,各种语言纷纷中招。本文结合PHP内核源码,聊一聊这种攻击的原理及实现。哈希表碰撞攻击的基本原理哈希表是一种查找效率极高的数据结构,很多语言都在内部实现了哈希表。PHP中的哈希表是一种极为重要的数据结构,不但用于表示Array数据类型,还在Zend虚拟机内部用于存储上下文环境信息(执行...原创 2019-08-27 17:47:31 · 210 阅读 · 0 评论 -
十七、PHP内核探索:解释器的执行过程 ☞ 引擎是如何执行PHP代码的
这里将介绍引擎内部执行一个PHP脚本的流程,以CLI SAPI为例子来对流程中核心的部分做简单介绍,省去一些初始化及清理操作。CLI(Command Line Interface)即PHP的命令行模式,现在此SAPI是默认安装的,我们在服务器上安装完PHP之后,一般会生成一个可执行文件,假设此文件为/usr/local/bin/php,那么我们在SHELL下可以用以下命令来执行一个PHP脚本...原创 2019-08-29 10:16:22 · 128 阅读 · 1 评论 -
十八、PHP内核探索:变量概述 ☞ 变量在PHP的内部是如何实现的呢
现代编程语言中的基本元素主要有:变量,流程控制接口,函数等等。我能否不使用变量来编写程序呢? 这显然是可以的,例如:<?phpecho "Hello NowaMagic";?>这个程序很简单,输出一个字符串内容。就和我们仅仅使用二进制也能编程一样,不使用变量也能完成大部分的工作,不使用变量我们的程序将丧失极大的灵活性, 变量可以让我们将值存储起来,以便在程序的其他地...原创 2019-08-29 10:17:30 · 66 阅读 · 0 评论 -
十九、PHP内核探索:变量存储与类型 ☞ 存储结构与变量类型
先回答前面一节的那个问题吧。<?php$foo = 10;$bar = 20; function change() { global $foo; //echo '函数内部$foo = '.$foo.'<br />'; //如果不把$bar定义为global变量,函数体内是不能访问$bar的 $bar = 0; $foo++;} ch...原创 2019-08-29 10:18:36 · 155 阅读 · 0 评论 -
二十、PHP内核探索:PHP中的哈希表 ☞ 哈希表是PHP实现中尤为关键的数据结构
PHP中使用最为频繁的数据类型非字符串和数组莫属,PHP比较容易上手也得益于非常灵活的数组类型。 在开始详细介绍这些数据类型之前有必要介绍一下哈希表(HashTable)。 哈希表是PHP实现中尤为关键的数据结构。哈希表在实践中使用的非常广泛,例如编译器通常会维护的一个符号表来保存标记,很多高级语言中也显式的支持哈希表。 哈希表通常提供查找(Search),插入(Insert),删除(Dele...原创 2019-08-29 10:19:40 · 73 阅读 · 0 评论 -
二十一、PHP内核探索:理解Zend里的哈希表 ☞ Zend HashTable源码分析
在PHP的Zend引擎中,有一个数据结构非常重要,它无处不在,是PHP数据存储的核心,各种常量、变量、函数、类、对象等都用它来组织,这个数据结构就是HashTable。HashTable在通常的数据结构教材中也称作散列表,哈希表。其基本原理比较简单(如果你对其不熟悉,请查阅随便一本数据结构教材或在网上搜索),但PHP的实现有其独特的地方。理解了HashTable的数据存储结构,对我们分析PHP...原创 2019-08-29 10:20:51 · 186 阅读 · 0 评论 -
二十二、PHP内核探索:PHP哈希算法设计 ☞ PHP中的Hash算法
Hash Table是PHP的核心,这话一点都不过分。PHP的数组、关联数组、对象属性、函数表、符号表等等都是用HashTable来做为容器的。PHP的HashTable采用的拉链法来解决冲突,这个自不用多说,我今天主要关注的就是PHP的Hash算法,和这个算法本身透露出来的一些思想。PHP的Hash采用的是目前最为普遍的DJBX33A (Daniel J. Bernstein, Time...原创 2019-08-29 10:21:48 · 168 阅读 · 0 评论 -
二十三、PHP内核探索:翻译一篇HashTables文章 ☞ PHP中的任何东西都是哈希表
In case you ever heard me talking about PHP internals I certainly mentioned something along the lines of "Everything in PHP is a HashTable" that's not true, but next to a zval the HashTable is one of ...原创 2019-08-29 10:22:48 · 176 阅读 · 0 评论 -
二十四、PHP内核探索:哈希碰撞攻击是什么? ☞ 攻击的原理及实现
最近哈希表碰撞攻击(Hashtable collisions as DOS attack)的话题不断被提起,各种语言纷纷中招。本文结合PHP内核源码,聊一聊这种攻击的原理及实现。哈希表碰撞攻击的基本原理哈希表是一种查找效率极高的数据结构,很多语言都在内部实现了哈希表。PHP中的哈希表是一种极为重要的数据结构,不但用于表示Array数据类型,还在Zend虚拟机内部用于存储上下文环境信息(执行...原创 2019-08-29 10:23:50 · 181 阅读 · 0 评论 -
二十五、PHP内核探索:常量的实现 ☞ 脱离C语言和数学讨论底层都是耍流氓
常量,顾名思义是一个常态的量值。它与值只绑定一次,它的作用在于有肋于增加程序的可读性和可靠性。 在PHP中,常量的名字是一个简单值的标识符,在脚本执行期间该值不能改变。 和变量一样,常量默认为大小写敏感,但是按照我们的习惯常量标识符总是大写的。 常量名和其它任何 PHP 标签遵循同样的命名规则。合法的常量名以字母或下划线开始,后面跟着任何字母,数字或下划线。在设定以后,常量的值无法更改 常量...原创 2019-08-29 10:24:26 · 128 阅读 · 0 评论 -
二十六、PHP内核探索:变量的存储 ☞ 变量存储在一个HashTable实现的符号表里
PHP中的变量类型和值是通过C语言实现的,内核具体是如何组织用户在PHP中定义的变量呢?Hash Table在ZE内核中被广泛使用,PHP变量也正是存储在一个HashTable实现的符号表里。当在PHP中调用一个函数或者类时,内核会创建一个新的符号表,这也是为什么在函数中无法使用函数外部定义的变量的原因。因为他们分属两个符号表,一个当前作用域,一个全局作用域。现在来看内核中是如何定义作用域...原创 2019-08-29 10:25:44 · 142 阅读 · 0 评论 -
二十七、PHP内核探索:变量的类型 ☞ PHP弱类型变量特性是如何实现?
所有的编程语言都要提供一种数据的存储与检索机制,PHP也不例外。其它语言大都需要在使用变量之前先定义,并且它的类型也是无法再次改变的,而PHP却允许程序猿自由的使用变量而无须提前定义,甚至可以随时随意的对已存在的变量转换成其它任何PHP支持的数据类型。在程序在运行的时候,PHP还会自动的根据需求转换变量的类型。如果你用过PHP,肯定体验过PHP的弱类型的变量体系。众所周知,PHP引擎是用C写的...原创 2019-08-30 14:56:24 · 151 阅读 · 0 评论 -
二十八、PHP内核探索:变量的值操作 ☞ 三个基础宏方便对变量的值进行操作
PHP内核提供了三个基础宏来方便我们对变量的值进行操作,这几个宏同样以Z_开头,并且P结尾和PP结尾的同上一节中的宏一样,分别代表这参数是指针还是指针的指针。此外,为了进一步方便我们的工作,内核中针对具体的数据类型分别定义了相应的宏。如针对IS_BOOL型的BVAL组合(Z_BVAL、Z_BVAL_P、Z_BVAL_PP)和针对IS_DOUBLE的DVAL组合(Z_DVAL、ZDVAL_P、ZDV...原创 2019-08-30 14:57:10 · 88 阅读 · 0 评论 -
二十九、PHP内核探索:变量的创建 ☞ 通过zval结构来实现
我们已经知道php变量在内核中其实是通过zval结构来实现的,也初步了如果设置一个zval结构的类型和值,这一节我们的目的便是在前两节的基础上,彻底掌握对zval结构的操控,其间将引入很多超棒的新的宏。在code的时候,我们很希望在内核中创建的zval可以让用户在PHP语言里以变量的形式使用,为了实现这个功能,我们首先要创建一个zval。最容易想到的办法便是创建一个zval指针,然后申请一块内...原创 2019-08-30 14:57:50 · 84 阅读 · 0 评论 -
三十、PHP内核探索:预定义变量 ☞ PHP脚本运行前将一些特殊变量加到符号表
大家都知道PHP脚本在执行的时候用户全局变量(在用户空间显式定义的变量)会保存在一个HashTable数据类型的符号表(symbol_table)中, 在PHP中有一些比较特殊的全局变量例如: $_GET,$_POST,$_SERVER等变量,我们并没有在程序中定义这些变量,并且这些变量也同样保存在符号表中, 从这些表象我们不难得出结论:PHP是在脚本运行之前就将这些特殊的变量加入到了符号表中了。...原创 2019-08-30 14:58:39 · 158 阅读 · 0 评论 -
三十一、PHP内核探索:变量的检索 ☞ zend_hash_find()函数
用户在PHP语言里定义的变量,我们能否在内核中获取到呢?答案当然是肯定的,下面我们就看如何通过zend_hash_find()函数来找到当前某个作用域下用户已经定义好的变量。zend_hash_find()函数是内核提供的操作HashTable的API之一,如果你没有接触过,可以先记住这么使用就可以了。{ zval **fooval; if (zend_hash_find(...原创 2019-08-30 14:59:33 · 495 阅读 · 0 评论 -
三十二、PHP内核探索:变量的类型转换 ☞ 内核提供了函数专门来实现类型转换
现在我们已经可以从符号表中获取用户在PHP语言里定义的变量了,是该做点其它事的时候了,举个比例,比如给它来个类型转换:-)。想想C语言中的类型转换细则,你的头是不是已经大了?但是变量的类型转换就是如此重要,如果没有,那我们的代码就会是下面这样了:void display_zval(zval *value){ switch (Z_TYPE_P(value)) { ca...原创 2019-08-30 15:00:20 · 147 阅读 · 0 评论 -
三十三、PHP内核探索:弱类型变量的实现 ☞ 如何用C实现这种弱类型?
PHP是弱类型,动态的语言脚本。在申明一个变量的时候,并不需要指明它保存的数据类型。<?php $var = 1; $var = "variable"; $var = 1.00; $var = array(); $var = new Object(); ?>动态变量,在运行期间是可以改变的,并且在使用前无需声明变量类型。那么,问题一、Zend引擎...原创 2019-08-30 15:01:04 · 153 阅读 · 1 评论 -
三十四、PHP内核探索:静态变量的实现 ☞ 它的值不会在函数调用结束后释放
通常意义上静态变量是静态分配的,他们的生命周期和程序的生命周期一样, 只有在程序退出时才结束期生命周期,这和局部变量相反,有的语言中全局变量也是静态分配的。 例如PHP和Javascript中的全局变量。静态变量可以分为:静态全局变量,PHP中的全局变量也可以理解为静态全局变量,因为除非明确unset释放,在程序运行过程中始终存在。 静态局部变量,也就是在函数内定义的静态变量,函数在执行...原创 2019-08-30 15:01:49 · 1124 阅读 · 0 评论