php8
jit介绍
- jit为opcache扩展的一部分,在运行时将某些操作码编译成cpu指令,这些指令就不需要zend vm在运行时再去解释。
- 是opcache的优化
- 目前只支持x86cpu
opcache过程
- 解析代码,查看opcache中是否有缓存,没有的话,走编译器,生成opcodes,经过优化器,生成优化后的代码,存储到opcodes cache缓存中,将opcode 放到zend vm进行执行。
- 如果开启了jit,再优化后的opcodes生成以后,会进行进行jit的编译,并将编译后的机器码放入到jit buffer中,下次执行发现有jit buffer,就会直接发给cpu执行,不在走zend vm引擎
zend介绍
Zend引擎,加载注册的扩展模块,然后读取对应的脚本文件,Zend引擎会对文件进行词法和语法分析,生成抽象语法树,接着抽象语法树被编译成Opcodes,如果开启了Opcache,编译的环节会被跳过从Opcache中直接读取Opcodes进行执行。
参考
jit 使用
jit配置
- opcache.jit=1205 // 每位对应一个配置
- 第一位,是否在生成机器码点时使用AVX指令,0不使用,1使用
- 第二位,寄存器分配策略,0 不使用寄存器分配 1 局部域分配 2 全局域分配,一般选2
- 第三位,jit触发策略,0 php脚本在入时 1 函数第一次被执行时 2 第一次运行后,jit调用次数最多的百分之(opcache.prof_threshold*100)的函数 3 当函数/方法执行超过N(N和opcache.jit_hot_func相关)以后jit 4 当函数方法的注释中含有@jit的时候对它进行jit 5 当一个Trace执行超过N次(和opcache.jit_hot_loop,jit_hot_return等相关)以后jit 常用0、3、5
- 第四位,jit优化策略,数值越大优化力度越大,0 不做jit 1 做opline之间的跳转部分你的jit 2 内敛opcode handler 调用 3 基于类型推断做函数级jit 4 基于类型推断,过程调用图做函数级jit 5 基于类型推断,过程调用图做脚本级jit
- opcache.jit其他选项
- disable,完全禁用,并在运行时无法启用
- off 禁用,但是运行时可以启用
- on 启用tracing模式
- tracing 1254的别名
- function 1205的别名
- opcache.jit_buffer_size=64MB // 设置缓存区大小,默认64MB
执行测试
- php -d opcache.jit=tracing xxx.php
-
开启jit对web应用的提升不大,对cpu密集型,提升较大
命名参数
- 使用标记,将参数的对应关系进行标记,在传参时,不需要对参数的位置进行固定,可以省略一些null的占位
- 位置传参和命名传参可以混用,但是位置传参要在命名传参前面
function a($name,$age){
echo $name.PHP_EOL;
echo $age.PHP_EOL;
}
a(age:18,name:'abc');
仅支持php8新增的函数或者自定义函数,不向下兼容
可变传参
不确定传参个数使用,会将所有多余的参数放入到一个数组中
function a($arg1,$arg2,...$args){
print_r($args);
}
a(1,2,3,4); // 输出[3,4]
// 如果使用命名传参就会反生变化
a(1,2,3,args:4); // 会输出 [3,'args':4] 会将参数名放入到键中
match表达式
- 完全匹配上,会将对应的内容进行返回
function condition($a) {
return $a;
}
$a = 1;
echo match($a) {
1 => '11', // 这里键使用字符串的会匹配不上
2,3 => '2||3', // 多值匹配,a=2或者3会打印2||3
condition($a) => '函数的返回值和传入的$a匹配上,会走这',
default=>'22'
}; // 会打印出11
// match 键可以是多个值,函数,常量等
异常处理
- 在php8以下,warning和notice不会终止脚本执行,可以利用@符号屏蔽报错
- php8错误级别进行了提升,并且会抛出很多异常,增加了异常的抛出
- 分为TypeError和ValueError
- typeError是类型错误
- valueError是类型正确了,可能值不正确
- TypeError和ValueError继承自Error类,Error类实现的是Throwable接口
substr('abc',[]); //报Fatal Error 抛出typeerror
try{
substr('abc',[]);
}catch(TypeError $e){
echo $e->getMessage();
}
// ValueError
try{
json_encode('a',true,-1);
}catch(ValueError $e){
echo $e->getMessage();
}
// 使用throw抛出typeerror value error
throw new ValueError("参数范围不正确");
箭头函数
$f = fn($a,$b)=>'a';
echo $f(1,2); // 输出a
echo (fn($a,$b)=>$a+$b;)(1,2);
其他函数等
str_contains()