香橙派装php_从安装到新特性浅析, 一文了解php8做了哪些改变

事情总在不断变化演进当中,依稀记得php7彼时才刚刚发布,恋恋不舍的从5.4系统升级到7.x,于是开始试着写类型声明、开始使用三元判断??等等... 想着什么时候写7也能像5系的那样得心应手,于是写着写着,php8发布了 。登录php官网即可看到醒目的标题:php8发布了!

下面就让咱们一起看看php8都带来了哪些改变和解决了什么痛点吧,话不多说,先安装走起吧安装php8 (macos 11.1)

从php官网下载源码:

wget https://www.php.net/distributions/php-8.0.0.tar.gz

...

下载完毕!

解压:

#解压

tar zxvf php-8.0.0.tar.gz

# 生成 configure 文件

./buildconf --force

# 配置构建流程

./configure --prefix=/usr/local/php80 \--with-config-file-path=/usr/local/php80 \--enable-cli \--enable-debug \--enable-fpm \--with-config-file-scandir=/usr/local/php80/etc/php.d/ \--without-iconv

执行无误的话大概是这样式滴

构建安装

make && sudo make install

漫长的安装完毕后配置文件

sudo cp php.ini-development /usr/local/php80/php.ini

安装成功,✿✿ヽ(°▽°)ノ✿

我本子里之前的版本是7.3.x的版本,这也是我现在工作的主力版本,所以我得处理下双版本问题,就在查看旧版本的时候,看到了扎心的一幕macos未来的版本将不再自带php

不过也无所谓,貌似macos之前自带的php我一次也没用过,咱们继续。。。8带来了哪些改变?

至于改变,官网给列的很清楚明白

什么?不喜英文?其实我也是。。。chrome翻译如下JIT (just in time)

其中最大也是最重要的当然也是喊了有几年的jit即时编译了,简单来讲就是一些频繁被执行的函数方法等会被jit机制转换成CPU级别的机器码直接执行,而不像之前一样通过zend vm执行,更亲和cpu,效率肯定会提升较大。至于技术细节 有兴趣的看官可以看这篇文章,大神写的很详细rhett:PHP JIT 技术详解​zhuanlan.zhihu.com

php8的JIT是在opcache的层面上提供的,它是在opcache优化的基础上,结合runtime信息再次优化,直接生成机器码。

opcache扩展可以自行安装下,安装好之后在原有的配置之外,添加两条jit的配置信息,贴上我的配置信息供参考

opcache.enable=1

opcache.memory_consumption=256

opcache.interned_strings_buffer=4

opcache.max_accelerated_files=8000

opcache.max_wasted_percentage=5

opcache.use_cwd=1

opcache.validate_timestamps=1

opcache.revalidate_freq=0

opcache.revalidate_path=0

opcache.save_comments=0

opcache.load_comments=0

opcache.jit=1205

opcache.jit_buffer_size=64M

最下面两个就是jit的配置啦,opcache.jit是有四个独立数字组成,从左到右分别是是否在生成机器码点时候使用AVX指令, 需要CPU支持:

0: 不使用

1: 使用寄存器分配策略:

0: 不使用寄存器分配

1: 局部(block)域分配

2: 全局(function)域分配JIT触发策略:

0: PHP脚本载入的时候就JIT

1: 当函数第一次被执行时JIT

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等有关)以后JITJIT优化策略,数值越大优化力度越大:

0: 不JIT

1: 做opline之间的跳转部分的JIT

2: 内敛opcode handler调用

3: 基于类型推断做函数级别的JIT

4: 基于类型推断,过程调用图做函数级别JIT

5: 基于类型推断,过程调用图做脚本级别的JIT

简单测试:

jit果真有传说中的那么强吗,下面测试一下。我在本地分别创建了两个虚拟环境,root指向同一个目录。php版本分别为

c.com:8.0.0

b.com:7.3.25

测试脚本为每次面试都要复习的冒泡排序,代码如下:

$stime=microtime(true); //获取程序开始执行的时间

function mao_pao($arr) {

$count = count($arr);

for ($i=0; $i < $count; $i++) {

for ($j=0; $j < $count; $j++) {

if (isset($arr[$j+1])) {

if ($arr[$j] > $arr[$j+1]) {

$temp = $arr[$j];

$arr[$j] = $arr[$j+1];

$arr[$j+1] = $temp;

}

}

}

}

return $arr;

}

for ($i=0; $i<=10000; $i++) {

$array[] = mt_rand(0, 10000);

}

mao_pao($array);

$etime=microtime(true);//获取程序执行结束的时间$total=$etime-$stime; //计算差值echo "$total";

为了减少误差 我随机生成一个固定数组

php8 vs php7

三次求平均值:8.0.0 with jit on7.3.25

1.22349905967713.6357760429382

由此可见性能提升还是明显的。(pis: 但是8如果关掉jit 测试性能还不如7 这块我也很疑惑,正在找原因。。。todo)

jit为啥能让执行性能提升?可以看下上面给的鸟哥的博客,在此就不赘述了。

Attributes (注解)

最近一直在用spring boot开发项目,给我印象最深的就是可以使用各种注释定义类,方法以及变量等,这样在代码书写比较优雅简洁的同时,提高了开发效率。现在php8的注解(Attributes)功能也来了

Attributes其实是依靠反射函数去实现价值的,以往也会用到php的反射函数,不过大多数情况下是用来自动生成API文档的时候才使用的,感觉没有太大的发挥空间。

/**

* @name 测试方法

* @author yangyanlei

*/

function test($params){}

$ref = new ReflectionFunction("test");

$doc = $ref->getDocComment();

print_r($doc);

执行获取信息如下:

/** * @name 测试方法 * @author yangyanlei */

这样简单粗暴的把注释里面的信息获取,然后再用字符串函数进行处理,不够规范也容易出错。

新的写法:

#[name("测试方法")]

#[author("yangyanlei")]

function test($params) {}

$ref = new ReflectionFunction("test");

print_r($ref->getAttributes("name")[0]->getArguments());

输出内容:

Array ( [0] => 测试方法 )

以后也可以这样实现注解及配置

#[Attribute]

class MyAttribute {

public function __construct($name, $value) {

print_r($name);

print_r($value);

}

}

#[MyAttribute("testname", "testvalue")]

function test($argument) {

}

$ref = new ReflectionFunction("test");

$ref->getAttributes("MyAttribute")[0]->newInstance();

程序输出:

testnametestvalue

虽然现在觉得好像用处不大,但是谁又能保证之后php不会出一个类似于spring boot注解的AOP开源框架呢,期待。。联合类型

自7开始,php已经支持类型声明,但是只支持单个类型声明,而联合声明是接收不同类型的值,而不是单个类型,语法指定T1|T2|...。之前不确定类型只能用?代替 ‍♂️

public function foo(Foo|Bar $input): int|float;

这个特性没什么可说的 不过有几个点需要注意可空联合类型:null类型可以作为联合类型的一部分 T1|T2|null因此可用于创建可为空的联合。

void是一个返回类型,指示函数不返回值。因此,它不能成为联合类型声明的一部分

match表达式

php8新增match表达式的支持,感觉就是switch的语法糖

function switchDemo($input) {

$res = 0;

switch ($input) {

case 1:

$res = 1;

break;

case 2:

$res = 2;

break;

default:

$res = 3;

}

echo $res . "\n";

}

echo switchDemo(1);

echo switchDemo(2);

echo switchDemo(3);

?>

输出:

1 2 3

match写法:

function matchdemo($input) {

echo match ($input) {

1 => 1,

2 => 2,

3 => 3

};

}

echo matchdemo(1);

echo matchdemo(2);

echo matchdemo(3);

?>

输出:

123

并且,类似switch的多个case一个block一样,match的多个条件也可以写在一起,比如:

$result = match($input) {

"true", "on" => 1,

"false", "off" => 0,

"null", "empty", "NaN" => NULL,

};

结语

以上,本文会随时更新补充,希望phper越来越好,希望php越来越好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值