研究 PHP opcode 是如何优化的

PHP运行原理之opcode 什么是opcode? opcode是PHP脚本编译后的中间语言(相似于Java语言的字节码–byte-code),是PHP引擎(Zend)执行的语言。 PHP引擎在执行PHP脚本时会分为四步来进行:1、扫描、词法分析:将PHP代码转换为token(语言片段) 2、语法分析:将token转换为简单而有意义的表达式 3、编译:将所有表达式转换成opcodes 4、执行:顺序执行(通常为由上至下)op... 阅读详情

本文基于编译原理,结合opcache扩展提供的优化器,以PHP编译基本单位op_array、PHP执行最小单位opcode为出发点。介绍编译优化技术在Zend虚拟机中的应用,梳理各个优化遍是如何一步步优化opcode来提高代码执行性能的。最后结合PHP语言虚拟机执行给出几点展望。

1.概述

PHP(本文所述案例PHP版本均为7.1.3)作为一门动态脚本语言,其在zend虚拟机执行过程为:读入脚本程序字符串,经由词法分析器将其转换为单词符号,接着语法分析器从中发现语法结构后生成抽象语法树,再经静态编译器生成opcode,最后经解释器模拟机器指令来执行每一条opcode。

在上述整个环节中,生成的opcode可以应用编译优化技术如死代码删除、条件常量传播、函数内联等各种优化来精简opcode,达到提高代码的执行性能的目的。

PHP扩展opcache,针对生成的opcode基于共享内存支持了缓存优化。在此基础上又加入了opcode的静态编译优化。这里所述优化通常采用优化器(Optimizer)来管理,编译原理中,一般用优化遍(Opt pass)来描述每一个优化。

整体上说,优化遍分两种:

  • 一种是分析pass,是提供数据流、控制流分析信息为转换pass提供辅助信息;
  • 一种是转换pass,它会改变生成代码,包括增删指令、改变替换指令、调整指令顺序等,通常每一个pass前后可dump出生成代码的变化。
2.几个概念说明

1)静态编译/解释执行/即时编译

静态编译(static compilation),也称事前编译(ahead-of-time compilation),简称AOT。即把源代码编译成目标代码,执行时在支持目标代码的平台上运行。

动态编译(dynamic compilation),相对于静态编译而言,指”在运行时进行编译”。通常情况下采用解释器(interpreter)编译执行,它是指一条一条的解释执行源语言。

JIT编译(just-in-time compilation),即即时编译,狭义指某段代码即将第一次被执行时进行编译,而后则不用编译直接执行,它为动态编译的一种特例。

上述三类不同编译执行流程,可大体如下图来描述:

2)数据流/控制流

编译优化需要从程序中获取足够多的信息,这是所有编译优化的根基。

编译器前端产生的结果可以是语法树亦可以是某种低级中间代码。但无论结果什么形式,它对程序做什么、如何做仍然没有提供多少信息。编译器将发现每一个过程内控制流层次结构的任务留给控制流分析,将确定与数据处理有关的全局信息任务留给数据流分析。

  • 控制流 是获取程序控制结构信息的形式化分析方法,它为数据流分析、依赖分析的基础。控制的一个基本模型是控制流图(Control Flow Graph,CFG)。单一过程的控制流分析有使用必经结点找循环、区间分析两种途径。
  • 数据流 从程序代码中收集程序的语义信息,并通过代数的方法在编译时确定变量的定义和使用。数据的一个基本模型是数据流图(Data Flow Graph,DFG)。通常的数据流分析是基于控制树的分析(Control-tree-based data-flow analysis),算法分为区间分析与结构分析两种。

3)op_array

类似于C语言的栈帧(stack frame)概念,即一个运行程序的基本单位(一帧),一般为一次函数调用的基本单位。此处,一个函数或方法、整个PHP脚本文件、传给eval表示PHP代码的字符串都会被编译成一个op_array。

实现上op_array为一个包含程序运行基本单位的所有信息的结构体,当然opcode数组为该结构最为重要的字段,不过除此之外还包含变量类型、注释信息、异常捕获信息、跳转信息等。

4)opcode

解释器执行(ZendVM)过程即是执行一个基本单位op_array内的最小优化opcode,按顺序遍历执行,执行当前opcode,会预取下一条opcode,直到最后一个RETRUN这个特殊的opcode返回退出。

这里的opcode某种程度也类似于静态编译器里的中间表示(类似于LLVM IR),通常也采用三地址码的形式,即包含一个操作符,两个操作数及一个运算结果。其中两个操作数均包含类型信息。此处类型信息有五种,分别为:

  • 编译变量(Compiled Variable,简称CV),编译时变量即为php脚本中定义的变量。
  • 内部可重用变量(VAR),供ZendVM使用的临时变量,可与其它opcode共用。
  • 内部不可重用变量(TMP_VAR),供ZendVM使用的临时变量,不可与其它opcode共用。
  • 常量(CONST),只读常量,值不可被更改。
  • 无用变量(UNUSED)。由于opcode采用三地址码,不是每一个opcode均有操作数字段,缺省时用该变量补齐字段。

类型信息与操作符一起,供执行器匹配选择特定已编译好的C函数库模板,模拟生成机器指令来执行。

opcode在ZendVM中以zend_op结构体来表征,其主体结构如下:

3.opcache optimizer优化器

PHP脚本经过词法分析、语法分析生成抽象语法树结构后,再经静态编译生成opcode。它作为向不同的虚拟机执行指令的公共平台,依赖不同的虚拟机具体实现(然对于PHP来说,大部分是指ZendVM)。

在虚拟机执行opcode之前,如果对opcode进行优化可得到执行效率更高的代码,pass的作用就是优化opcode,它作用于opcde、处理opcode、分析opcode、寻找优化的机会并修改opcode产生更高执行效率的代码。

1)ZendVM优化器简介

在Zend虚拟机(ZendVM)中,opcache的静态代码优化器即为zend opcode optimization。

为观察优化效果及便于调试,它也提供了优化与调试选项:

  • optimizationlevel (opcache.optimizationlevel=0xFFFFFFFF) 优化级别,缺省打开大部分优化遍,用户亦通过传入命令行参数控制关闭
  • optdebuglevel (opcache.optdebuglevel=-1) 调试级别,缺省不打开,但提供了各优化前后opcode的变换过程

执行静态优化所需的脚本上下文信息则封装在结构zend_script中,如下:

typedef struct _zend_script {  
    zend_string   *filename;        //文件名
    zend_op_array  main_op_array;   //栈帧
    HashTable      function_table;  //函数单位符号表信息
    HashTable      class_table;     //类单位符号表信息
} zend_script;

上述三个内容信息即作为输入参数传递给优化器供其分析优化。当然与通常的PHP扩展类似,它与opcode缓存模块一起(zend_accel)构成了opcache扩展。其在缓存加速器内嵌入了三个内部API:

  • zendoptimizerstartup 启动优化器
  • zendoptimizescript 优化器实现优化的主逻辑
  • zendoptimizershutdown 优化器产生的资源清理

关于opcode缓存,也是opcode非常重要的优化。其基本应用原理是大体如下:

虽然PHP作为动态脚本语言,它并不会直接调用GCC/LLVM这样的整套编译器工具链,也不会调用Javac这样的纯前端编译器。但每次请求执行PHP脚本时,都经历过词法、语法、编译为opcode、VM执行的完整生命周期。

除去执行外的前三个步骤基本就是一个前端编译器的完整过程,然而这个编译过程并不会快。假如反复执行相同的脚本,前三个步骤编译耗时将严重制约运行效率,而每次编译生成的opcode则没有变化。因此可在第一次编译时把opcode缓存到某一个地方,opcache扩展即是将其缓存到共享内存(Java则是保存到文件中),下次执行相同脚本时直接从共享内存中获取opcode,从而省去编译时间。

opcache扩展的opcode 缓存流程大致如下:

由于本文主要集中讨论静态优化遍,关于缓存优化的具体实现此处不展开。

2)ZendVM优化器原理

依“鲸书”(《高级编译器设计与实现》)所述,一个优化编译器较为合理的优化遍顺序如下:

上图中涉及的优化从简单的常量、死代码到循环、分支跳转,从函数调用到过程间优化,从预取、缓存到软流水、寄存器分配,当然也包含数据流、控制流分析。

当然,当前opcode优化器并没有实现上述所有优化遍,而且也没有必要实现机器相关的低层中间表示优化如寄存器分配。

opcache优化器接收到上述脚本参数信息后,找到最小编译单位。以此为基础,根据优化pass宏及其对应的优化级别宏,即可实现对某一个pass的注册控制。

注册的优化中,按一定顺序组织串联各优化,包含常量优化、冗余nop删除、函数调用优化的转换pass,及数据流分析、控制流分析、调用关系分析等分析pass。

zendoptimizescript及实际的优化注册zend_optimize流程如下:

zend_optimize_script(zend_script *script,  
      zend_long optimization_level, zend_long debug_level)
    |zend_optimize_op_array(&script->main_op_array, &ctx);
        遍历二元操作符的常量操作数,由运行时转化为编译时(反向pass2)
        实际优化pass,zend_optimize
        遍历二元操作符的常量操作数,由编译时转化为运行时(pass2)
    |遍历op_array内函数zend_optimize_op_array(op_array, &ctx);
    |遍历类内非用户函数zend_optimize_op_array(op_array, &ctx);
       (用户函数设static_variables)
    |若使用DFA pass & 调用图pass & 构建调用图成功
         遍历二元操作符的常量操作数,由运行时转化为编译时(反向pass2)
         设置函数返回值信息,供SSA数据流分析使用
         遍历调用图的op_array,做DFA分析zend_dfa_analyze_op_array
         遍历调用图的op_array,做DFA优化zend_dfa_optimize_op_array
         若开调试,遍历dump调用图的每一个op_array(优化变换后)
         若开栈矫正优化,矫正栈大小adjust_fcall_stack_size_graph
         再次遍历调用图内的的所有op_array,
           针对DFA pass变换后新产生的常量场景,常量优化pass2再跑一遍
         调用图op_array资源清理
    |若开栈矫正优化
          矫正栈大小main_op_array
          遍历矫正栈大小op_array
    |清理资源

该部分主要调用了SSA/DFA/CFG这几类用于opcode分析pass,涉及的pass有BB块、CFG、DFA(CFG、DOMINATORS、LIVENESS、PHI-NODE、SSA)。

用于opcode转换的pass则集中在函数zend_optimize内,如下:

zend_optimize  
|op_array类型为ZEND_EVAL_CODE,不做优化
|开debug,    可dump优化前内容
|优化pass1,  常量替换、编译时常量操作变换、简单操作转换
|优化pass2    常量操作转换、条件跳转指令优化
|优化pass3    跳转指令优化、自增转换
|优化pass4    函数调用优化(主要为函数调用优化)
|优化pass5    控制流图(CFG)优化
 |构建流图
 |计算数据依赖
 |划分BB块(basic block,简称BB,数据流分析基本单位)
 |BB块内基于数据流分析优化
 |BB块间跳转优化
 |不可到达BB块删除 
 |BB块合并
 |BB块外变量检查 
 |重新构建优化后的op_array(基于CFG)
 |析构CFG     
|优化pass6/7  数据流分析优化
 |数据流分析(基于静态单赋值SSA)
  |构建SSA
  |构建CFG  需要找到对应BB块序号、管理BB块数组、计算BB块后继BB、标记可到达BB块、计算BB块前驱BB
  |计算Dominator树
  |标识循环是否可简化(主要依赖于循环回边)
  |基于phi节点构建完SSA  def集、phi节点位置、SSA构造重命名
  |计算use-def链
  |寻找不当依赖、后继、类型及值范围值推断
 |数据流优化  基于SSA信息,一系列BB块内opcode优化
 |析构SSA
|优化pass9    临时变量优化
|优化pass10   冗余nop指令删除
|优化pass11   压缩常量表优化

还有其他一些优化遍如下:

优化pass12   矫正栈大小
优化pass15   收集常量信息
优化pass16   函数调用优化,主要是函数内联优化

除此之外,pass 8/13/14可能为预留pass id。由此可看出当前提供给用户选项控制的opcode转换pass有13个。但是这并不计入其依赖的数据流/控制流的分析pass。

3)函数内联pass的实现

通常在函数调用过程中,由于需要进行不同栈帧间切换,因此会有开辟栈空间、保存返回地址、跳转、返回到调用函数、返回值、回收栈空间等一系列函数调用开销。因此对于函数体适当大小情况下,把整个函数体嵌入到调用者(Caller)内部,从而不实际调用被调用者(Callee)是一个提升性能的利器。

由于函数调用与目标机的应用二进制接口(ABI)强相关,静态编译器如GCC/LLVM的函数内联优化基本是在指令生成之前完成。

ZendVM的内联则发生在opcode生成后的FCALL指令的替换优化,pass id为16,其原理大致如下:

| 遍历op_array中的opcode,找到DO_XCALL四个opcode之一
| opcode ZEND_INIT_FCALL
| opcode ZEND_INIT_FCALL_BY_NAMEZ
     | 新建opcode,操作码置为ZEND_INIT_FCALL,计算栈大小,
        更新缓存槽位,析构常量池字面量,替换当前opline的opcode
| opcode ZEND_INIT_NS_FCALL_BY_NAME
     | 新建opcode,操作码置为ZEND_INIT_FCALL,计算栈大小,
        更新缓存槽位,析构常量池字面量,替换当前opline的opcode
| 尝试函数内联
     | 优化条件过滤 (每个优化pass通常有较多限制条件,某些场景下
         由于缺乏足够信息不能优化或出于代价考虑而排除) 
        | 方法调用ZEND_INIT_METHOD_CALL,直接返回不内联
        | 引用传参,直接返回不内联
        | 缺省参数为命名常量,直接返回不内联
     | 被调用函数有返回值,添加一条ZEND_QM_ASSIGN赋值opcode
     | 被调用函数无返回值,插入一条ZEND_NOP空opcode 
     | 删除调用被内联函数的call opcode(即当前online的前一条opcode)

如下示例代码,当调用fname()时,使用字符串变量名fname来动态调用函数foo,而没有使用直接调用的方式。此时可通过VLD扩展查看其生成的opcode,或打开opcache调试选项(opcache.optdebuglevel=0xFFFFFFFF)亦可查看。

function foo() { }  
$fname = 'foo';

开启debug后dump可看出,发生函数调用优化前opcode序列(仅截取片段)为:

ASSIGN CV0($fname) string("foo")  
INIT_FCALL_BY_NAME 0 CV0($fname)  
DO_FCALL_BY_NAME

INIT_FCALL_BY_NAME这条opcode执行逻辑较为复杂,当开启激进内联优化后,可将上述指令序列直接合并成一条DO_FCALL string(“foo”)指令,省去间接调用的开销。这样也恰好与直接调用生成的opcode一致。

4)如何为opcache opt添加一个优化pass

根据以上描述,可见向当前优化器加入一个pass并不会太难,大体步骤如下:

  • 先向zend_optimize优化器注册一个pass宏(例如添加pass17),并决定其优化级别。
  • 在优化管理器某个优化pass前后调用加入的pass(例如添加一个尾递归优化pass),建议在DFA/SSA分析pass之后添加,因为此时获得的优化信息更多。
  • 实现新加入的pass,进行定制代码转换(例如zendoptimizefunc_calls实现一个尾递归优化)。针对当前已有pass,主要添加转换pass,这里一般也可利用SSA/DFA的信息。不同于静态编译优化一般是在贴近于机器相关的低层中间表示优化,这里主要是在opcode层的opcode/operand相应的一些转换。
  • 实现pass前,与函数内联类似,通常首先收集优化所需信息,然后排除掉不适用该优化的一些场景(如非真正的尾不递归调用、参数问题无法做优化等)。实现优化后,可dump优化前后生成opcode结构的变化是否优化正确、是否符合预期(如尾递归优化最终的效果是变换函数调用为forloop的形式)。
4.一点思考

以下是对基于动态的PHP脚本程序执行的一些看法,仅供参考。

由于LLVM从前端到后端,从静态编译到jit整个工具链框架的支持,使得许多语言虚拟机都尝试整合。当前PHP7时代的ZendVM官方还没采用,原因之一虚拟机opcode承载着相当复杂的分析工作。相比于静态编译器的机器码每一条指令通常只干一件事情(通常是CPU指令时钟周期),opcode的操作数(operand)由于类型不固定,需要在运行期间做大量的类型检查、转换才能进行运算,这极度影响了执行效率。即使运行时采用jit,以byte code为单位编译,编译出的字节码也会与现有解释器一条一条opcode处理类似,类型需要处理、也不能把zval值直接存在寄存器。

以函数调用为例,比较现有的opcode执行与静态编译成机器码执行的区别,如下图:

类型推断

在不改变现有opcode设计的前提下,加强类型推断能力,进而为opcode的执行提供更多的类型信息,是提高执行性能的可选方法之一。

多层opcode

既然opcode承担如此复杂的分析工作,能否将其分解成多层的opcode归一化中间表示( intermediate representation, IR)。各优化可选择应用哪一层中间表示,传统编译器的中间表示依据所携带信息量、从抽象的高级语言到贴近机器码,分成高级中间表示(HIR) 、中级中间表示(MIR)、低级中间表示(LIR)。

pass管理

关于opcode的优化pass管理,如前文鲸书图所述,应该尚有改进空间。虽然当前分析依赖的有数据流/控制流分析,但仍缺少诸如过程间的分析优化,pass管理如运行顺序、运行次数、注册管理、复杂pass分析的信息dump等相对于llvm等成熟框架仍有较大差距。

JIT

ZendVM实现大量的zval值、类型转换等操作,这些可借助LLVM编译成机器码用于运行时,但代价是编译时间极速膨胀。当然也可采用libjit。


深入理解OPCODE缓存:APC与XCache的设置与优化 本文深入探讨了使用APC和XCache作为Opcode缓存工具以提高PHP应用性能的方法。通过对比无缓存状态和使用默认设置的APC,我们看到了性能的提升。文章详细分析了APC的配置设置,包括如何通过php.ini文件调整缓存大小、缓存策略以及如何使用APC管理工具进行监控。此外,还介绍了XCache作为另一种选择,包括其安装、配置及使用,以及如何通过不同的设置选项来优化性能。 阅读详情

相关推荐

Ardupilot姿态控制详解(完结篇)

本文主要是对过去写的一些APM中姿态控制流程及函数博文的汇总。 按照之前写的博文以及个人认为的学习顺序,给出APM姿态控制器的学习顺序如下: APM姿态旋转理论基础 Ardupilot姿态控制器 PID控制流程(整定后的P控制器) 详解APM的开方控制器sqrt_controller Ardupilot前馈及平滑函数input_euler_angle_roll_pitch_yaw解析 Ardupilot倾转分离函数thrust_heading_rotation_angles Ardupilot四元数姿态控制

moumde的博客 7024

PHP的opcode是干什么的?底层原理是什么?

这些中间代码是 PHP 引擎在执行 PHP 脚本时的一种内部格式,可以更高效地执行 PHP 代码,避免了每次运行时都需要解析 PHP 代码的开销,同时也能减少内存的占用。对于 PHP 引擎来说,opcode 数组是一种更为高效的执行方式,因为它比源代码更紧凑,减少了 PHP 引擎解析代码的时间,同时 opcode 数组还能够被缓存到内存中,加快脚本的再次执行速度。总之,PHP 的 opcode 是一种中间格式,能够更高效地执行 PHP 代码,同时也能减少内存的占用,提高 PHP 脚本的执行速度。

长风破浪会有时的博客 592

手把手教你用Cadence Virtuoso完成LNA全套仿真:基于SpectreRF手册的实战补充

本文详细指导如何使用Cadence Virtuoso和SpectreRF完成LNA的全套仿真,涵盖噪声仿真、增益压缩、THD分析及双音IP3测量等关键步骤。针对官方手册中的常见问题,提供了12个实战解决方案,包括hbnoise函数选择、双音信号源配置等,帮助工程师高效完成射频IC设计。

weixin_29102619的博客 524

PHP如何使用opcode?底层原理是什么?

在 PHP 中,Opcode 编译器(Zend Engine)是一个将 PHP 代码转换成可执行的字节码的程序,以便 PHP 可以执行这些代码。总之,Opcode 是 PHP 代码的编译后的二进制表示形式,通过缓存和执行这些 Opcode,PHP 可以提高代码的性能和响应速度。为了避免每次运行 PHP 代码时都要重新编译代码,PHP 引擎可以将编译好的 Opcode 缓存起来,这样下次运行相同的代码时,就可以直接从缓存中读取 Opcode,从而提高性能。

长风破浪会有时的博客 726

【JS】自定义上传组件,文件上传与回显,自定义进度条显示(基于element-plus与axios)

公司是做B 端产品的,有sass平台也有源码交付的项目,最近开发了很多小系统,这里记录一下开发遇到的问题。 需要定制一个上传组件,要求可以自定义文件存储路径,自定义可上传的文件类型,限制文件大小等,并且提供基础的文件回显功能,例如上传一张图片到服务器指定目录的`/file`文件夹下面,并且实现可以查看预览的功能。

余浩的博客 1162

玩转Zabbix智能告警:降噪、排班、认领、升级、IM协同

集成Zabbix告警到FlashDuty,获得告警降噪、智能排班、IM协同等能力

n9ecommunity的博客 1040

PHP获取Opcode及C源码

在开始之前, 必须要先介绍一下是什么.众所周知, 在执行的时候, 会将后缀的文件预先编译为字节码文件, 加载字节码文件进行解释执行. 而字节码文件存在的意义, 就是为了加速执行.那么的与之类似, 也是从文件到执行的过程中, 所生成的预编译中间文件.或者也可以这样粗鲁的理解, 程序是由写的二进制程序, 就是将文件翻译为代码的结果.有什么用我们最后再说, 先让我们看一下它长什么样子如何获得文件的呢? 在的源码中, 可以通过函数获取代码解析后的. 但是我们要是为了获取得深入到, 是在有些得不偿失. 好在, 已经有

烟草的香味的博客 1570

ROS2中间件选型指南:FastDDS与CycloneDDS零拷贝机制对比与实战

在机器人开发中,通信中间件是连接分布式节点的核心纽带,其性能直接影响系统的实时性与可靠性。DDS作为ROS2默认的通信标准,通过发布订阅模型和QoS策略,为高频大带宽场景提供了灵活的数据分发能力。并行计算与高性能传输的需求,推动了零拷贝技术的演进——从传统序列化到共享内存乃至指针传递,旨在减少数据复制开销、降低延迟。在激光雷达点云、相机图像等场景下,中间件的选型尤为关键。FastDDS凭借与ROS2的深度集成和丰富文档成为入门首选,而CycloneDDS在低延迟和资源占用上表现更优,借助iceoryx实现了

weixin_28726391的博客 254

PHP的Opcode到底是什么时候出现的?

PHP 3-4时代:Opcode是解释执行的优化手段。PHP 5.5时代:OPcache让Opcode缓存成为标配,解决了PHP的“启动慢”问题。PHP 7-8时代:Opcode的极致优化(如JIT)使PHP在高并发场景中可与Go、Node.js等语言竞争。理解Opcode的演进,有助于开发者把握PHP性能优化的核心逻辑——通过减少重复编译、提升执行效率,让动态语言获得接近静态语言的性能表现。

长风破浪会有时的博客 1154

高频网络协议与编程IO相关面试基本问题和知识点整理

网络IO相关基本高频面试基本问题和知识点整合

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 173万+

Agent Harness Engineering: AI Agent 执行管控与安全沙箱 原理与最佳实践

我们正站在计算范式转移的历史节点上。2024-2026 年间,AI 系统从被动的内容生成器(Generative AI)演变为主动的行动执行者(Agentic AI)。这一转变的根本特征是:根据 2026 年初的行业数据:然而,能力的提升伴随着风险的指数级增长。2024-2026 年间发生的多起标志性安全事件揭示了 Agent 系统的脆弱性:案例 1:Slack AI 数据外泄事件(2024 年 8 月)案例 2:制造业供应链攻击(2026 年 Q3)案例 3:Arup 深度诈骗案(2026 年 9 月)这

AI天才研究院 1669

php内核总结_php内核分析之opcode

php内核分析之opcode在做PHP项目之前首先要对所运用的知识了解,下面是百分网小编精心为大家整理的php内核分析之opcode,希望对有需要的人有帮助,更多内容请关注应届毕业生网!这里阅读的php版本为PHP-7.1.0 RC3,阅读代码的平台为linux查看opcodephp是先把源码解析成opcode,然后再把opcode传递给zend_vm进行执行的。// 一个opcode的结构str...

weixin_36277054的博客 434

Windows密码忘了怎么办?一分钟看懂Windows密码底层机制:无需重装系统也能无痕找回登录密码

忘记Windows开机密码,不一定非得重装系统!本文手把手教你通过提取NTLM Hash值实现“无痕找回密码”,无需PE、无需清除密码,对系统零修改 🛡️ 搭配mimikatz与在线解密平台,小白也能快速上手,了解Windows密码底层机制 🔐

XiaoqiangClub的博客 126

php opcode and autoload,PHP autoload和spl_autoload自动加载机制详解(3)

(2) PHP的autoload机制的实现我 们知道,PHP文件的执行分为两个独立的过程,第一步是将PHP文件编译成普通称之为OPCODE的字节码序列(实际上是编译成一个叫做 zend_op_array的字节数组),第二步是由一个虚拟机来执行这些OPCODE。PHP的所有行为都是由这些OPCODE来实现的。因此,为了研 究PHP中autoload的实现机制,我们将autoload.php文件编译成...

weixin_29359765的博客 202

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

php xingnengfenxi_PHP 性能分析第三篇: 性能调优实战

在本系列的 第一篇 中,我们介绍了 XHProf 。而在 第二篇 中,我们深入研究了 XHGui UI, 现在最后一篇,让我们把 XHProf /XHGui 的知识用到工作中!性能调优不用运行的代码才是绝好的代码。其他只是好的代码。所以,性能调优时,最好的选择是首先确保运行尽可能少的代码。OpCode 缓存首先,最快且最简单的选择是启用 OpCode 缓存。OpCode 缓存的更多信息可以在 这里...

weixin_39602571的博客 129

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

关于PHP商城系统性能优化

最近在研究商城系统源码,在想怎么去更好的优化,一般来说,性能优化可先从大的方向开始考虑,从对影响性能比较大的因素来考虑,比如现在使用PHP5.7,性能可以成倍提高,这些都是客观因素,类似现在网上的开源商城,类似DSmall开源商城系统这类,基本都能支持高版本PHP,最后考虑的应该是PHP语法细节上。 PHP部署环境 单台服务器常用apache+php和nginx+php-fpm方式部署,我们...

weixin_43187724的博客 576

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

使用机器学习检测PHP Webshell的研究实践

Webshell知多少 Webshell是以PHP、ASP、JSP或CGI等网页文件形式存在的一种代码执行环境。在网络攻击过程中,Webshell是一种常用的恶意脚本,攻击者可以利用它在Web服务器上执行系统命令、窃取数据等。在入侵网站过程中,攻击者通常需要以各种方式获取Webshell,从而获得网站的控制权,再进行入侵。此外,攻击者入侵内网的肉鸡后,为了维持可用的传输通道,也需要创建肉鸡主动连接攻击者的反弹Webshell 。 Webshell具有隐蔽、便捷等特点,由于PHP语法灵活,通过隐藏敏感函数

olga5abl的博客 1123

深入浅出php,深入浅出PHP(Exploring PHP)

一直以来,横观国内的PHP现状,很少有专门介绍PHP内部机制的书。呵呵,我会随时记录下研究的心得,有机会的时候,汇总成书。:)今天这篇,我内心是想打算做为一个导论:PHP是一个被广泛应用的脚本语言,因为它的成功,所以很多时候,我们应用PHP的时候是更不不需要考虑底层到底是怎么实现的。我相信大多数的PHP程序 员是不会去考虑这一点的。从我接触PHP开始,到今天也就是3年,这三年里,前俩年我一直都是在...

weixin_36271649的博客 252

php性能极限,网站极限优化之php优化

这段时间忙死了,早上一大清早就要起来学计算机英语,听商务英语,前些日子搞数据库优化研究已经有了结果,现在就剩下php优化了,当然了,人各有志,只是发表下个人的看法,大家可以踊跃发表自己的意见,一下内容仅供参考,生产部署出了问题,与本人无关: 说到网站的建设那是相当的麻烦,不过现在有很多大师提出了很多有建设性的方法,我这里主要是针对mvc 模板引擎来讲,而他们两个东东都是和php有着紧密的联系的,当...

weixin_39900676的博客 170

php编译流程_如何编译php文件

PHP是解析型高级语言,事实上从Zend内核的角度来看PHP就是一个普通的C程序,它有main函数,我们写的PHP代码是这个程序的输入,然后经过内核的处理输出结果,内核将PHP代码"翻译"为C程序可识别的过程就是PHP的编译。推荐课程:PHP教程C程序在编译时将一行行代码编译为机器码,每一个操作都认为是一条机器指令,这些指令写入到编译后的二进制程序中,执行的时候将二进制程序load进相应的内存区域...

weixin_39815410的博客 496

PHPPHP揭秘:用PHP编写PHP虚拟机的革命性项目,你需要知道的一切

PHPPHP是一个用PHP语言编写的PHP虚拟机实现,它通过创新的方式让开发者能够在PHP环境中运行PHP代码,为PHP生态系统带来了全新的可能性。这个项目不仅展示了PHP语言的灵活性和强大功能,还为学习虚拟机原理和PHP内部工作机制提供了绝佳的实践案例。 ## 🤔 什么是PHPPHP?为什么它如此特别? PHPPHP的核心概念非常有趣:**用PHP语言来实现一个能够解释和执行PHP代码的虚

gitblog_00075的博客 315

PHP项目性能优化

PHP项目性能优化的三个层次 PHP语言层级 PHP周边(服务器,数据库,webserver) PHP底层 语言层级 尽量使用PHP原生函数和常量,类 如果要实现的功能有原生PHP函数,则不要自己用PHP实现 尽量使用性能更高的内置函数 比如isset和array_key_exists都可以使用,则使用isset 尽量不要使用错...

weixin_33675507的博客 167

PHP内部机制浅析与VLD工具实战

PHP代码的执行并非直接运行,而是经过Zend引擎的多层处理。这个处理流程主要包括词法分析、语法分析和opcode执行三个阶段,就像把一篇文章先拆解成单词,再分析句子结构,最后理解含义的过程。通过PECL安装后,只需在php.ini中加载扩展,就能在运行时看到代码的底层实现。Zend引擎是支持150条指令的复杂指令集虚拟机,它抽象了底层硬件差异,使PHP代码能在不同操作系统上运行。Zend引擎首先调用词法分析器,这个阶段会去除代码中的空格和注释,把源代码切割成有意义的token序列。表示以写模式获取变量。

BlueTiger92的博客 399
上一篇: 前面有人贡献,后辈才有强大的靠山
下一篇: 调试器工作原理之(三):研究调试信息
linuxprobe2017
博客等级 码龄10年 123粉丝 294原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值