PHP执行代码过程
php每次请求都会经历以下步骤
- 启动Zend引擎,加载配置,加载模块
- Scaning:扫描 ,也叫Lexing,把人类写的代码转换成语言片段(Tokens)
- Parsing:解析,将语言片段转换成简单表达式
- Compilation: 编译, 将表达式编译成opcode(字节码)
- Execution: 执行,zend vm顺序执行opcode
cli/cgi 模式每次都要执行全部步骤,php-fpm可以省略第一步,启用opcache时,可以省略2,3,4步
opcache
开启opcache,将opcode缓存起来(内存中),可以省略PHP执行的1,2步骤,直接执行opcache中的opcache。
可以极大减少CPU和内存开销,但对I/O密集的提升不是很大
如图:开启opcache会增加执行步骤
- 执行前判断是否存在opcache
- 首次执行会将opcode缓存起来
//opcache扩展位置
zend_extension=opcache.so
//启用opcache
opcache.enable=1
使用共享内存大小
opcache.memory_consumption=200
文件检测周期,以下2个配置代表3600秒更新1次缓存
revalidate_freq=3600 //3600秒更新1次缓存
opcache.validate_timestamps=1;//为0时revalidate_freq被忽略
opcache缺点
- 额外占用内存用来存储opcache
- 代码不能马上生效,要等缓存更新了才能生效 (revalidate_freq)
开头使用opcache_reset()函数,或者重启服务器来清空缓存
jit
PHP新加入,适合cpu密集型性能提升,JIT不是原来Opcache优化的替代,是增强
JIT在Opcache优化之后的基础上,再次优化,直接生成机器码,直接由CPU执行(不在需要ZEND VM虚拟机执行),目前PHP8只支持x86架构的CPU
PHP8的JIT是在Opcache之中提供的,集成在Opcache中
过程:
再生成opcode后,zend VM判断是否开启jit,未开启则zend VM接管,若开启了jit, 如果开启,则读取机器码中的jit buffer代码片段(以前缓存好的),直接让CPU托管执行。
PHP7常用新特性
- ?? 运算符
- 函数返回值类型声明,declare(strict_types=1) 声明强制模式
- 函数参数类型声明
- use批量声明
use some/namespace/{ClassA, ClassB, ClassC as C};
- <=> 太空船运算符
$a = 1;
$b = 2;
$c = $a<=>$b;
echo $c; //a:b 小中大分别返回 -1,0,1