php8新特性全览【超详细】
2022-07-28 15:09:43
136
{{single.collect_count}}
题外话:

PHP 8.0 是 PHP 语言的重大更新。
它包含许多新功能和优化,包括命名参数、联合类型、属性、构造函数属性提升、匹配表达式、空安全运算符、JIT,以及类型系统、错误处理和一致性方面的改进。
废话不多说,开车

1.便利的命名参数

也就是说在传参的时候可以跳过可选参数, 格式如 argName:value, 如示例中的“c:44”, 表示将44传给c

function namedArgs($a, $b=1, $c=2, $d=3) {var_dump($a);var_dump($b);var_dump($c);var_dump($d);}namedArgs(1, c:44);

// 运行结果如下:
在这里插入图片描述

2.构造器的提升

可以使用更简便的方法初始化属性,如下,可在构造方法括号中初始化对象的属性,并指定属性的权限

class People {public function __construct(public int $age=10,private string $name="lilith",) {}public function getName() {return $this->name;}}$a = new People(11, 'zhangsan');var_dump($a->age); // 11//var_dump($a->name); // 报错var_dump($a->getName());// zhangsan
3.联合类型

可以同时指定形参的多种类型 格式为 int | string | array

<?phpdeclare(strict_types=1);function UnionTypeTest(int|string|float $arg) {var_dump($arg);}UnionTypeTest(1);UnionTypeTest("1");UnionTypeTest(1.1);UnionTypeTest([1]); // 报错 Fatal error: Uncaught TypeError: UnionTypeTest(): Argument #1 ($arg) must be of type string|int|float, array given?>
4. match 表达式,挺有意思

可在某些情况下代替switch

$testVal = "101";$a = match ($testVal) {101 => 'num:101','101' => 'string:101',default => 'I don\'t know',};var_dump($a); // string(10) "string:101"

注意事项:
Match 是一个表达式,这意味着它的结果可以存储在变量中或返回。
匹配分支只支持单行表达式,不需要break
Match 进行严格的比较。

5. Nullsafe operator

解决php7 时代访问对象子属性的痛点
格式 $a?->b?->c?->d

<?phpclass C {public function __construct(public string $name='ccccc'){}}class B {public function __construct(public C $c){}}class A {public function __construct(public B $b){}}$a = new A(new B(new C));// 如要访问c的name属性/** * php 7的写法 */if (!is_null($a)) {if (!is_null($a->b)) {if (!is_null($a->b->c)) {echo $a->b->c->name;}}}/** * php 8的写法 */echo $a?->b?->c?->name;?>
6. string 与 num的比较

在与数字字符串进行比较时,PHP 8 使用数字比较。 否则,它将数字转换为字符串并使用字符串比较。

var_dump('123' == 123); // php7php8truevar_dump('123s' == 123); // php7 truephp8false
7.内部函数的一致类型错误

传入不合适的参数时,以前会报warning,现在是error.

/** * php 7 */strlen([]); // Warning: strlen() expects parameter 1 to be string, array givenarray_chunk([], -1); // Warning: array_chunk(): Size parameter expected to be greater than 0/** * php 8 */strlen([]); // TypeError: strlen(): Argument #1 ($str) must be of type string, array givenarray_chunk([], -1); // ValueError: array_chunk(): Argument #2 ($length) must be greater than 0
8. 注解 【存储php元数据】

这个算是一个比较大的变动,所以放最后讲
先看一个例子

<?php// 自定义一个注解类,注解的目标类型为METHOD,表明这个注解可以用在方法上, is_repeatable表示注解可重复#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]class AutoInjector {public function __construct(public string $data='test') {}}class TestObject {// 在方法上使用注解#[AutoInjector('annotation1'), AutoInjector("annotation2")]public function getLoaderData() {}}// 使用反射$objRef = new ReflectionClass(TestObject::class);$objMethod = $objRef->getMethod('getLoaderData');// 获取注解类$annoRefs = $objMethod->getAttributes('AutoInjector');foreach ($annoRefs as $annoRef) {$annoObj = $annoRef->newInstance();var_dump($annoObj->data);}// output:/** * string(11) "annotation1" * string(11) "annotation2" */

注解可以用来存储php元数据,如上 TestObject的getLoaderData上的注解中存储了 AutoInjector,注解作为方法getLoaderData的属性而存在,在运行时,可以通过反射API取用。
详细用法传送门

回帖
全部回帖({{commentCount}})
{{item.user.nickname}} {{item.user.group_title}} {{item.friend_time}}
{{item.content}}
{{item.comment_content_show ? '取消' : '回复'}} 删除
回帖
{{reply.user.nickname}} {{reply.user.group_title}} {{reply.friend_time}}
{{reply.content}}
{{reply.comment_content_show ? '取消' : '回复'}} 删除
回帖
收起
没有更多啦~
{{commentLoading ? '加载中...' : '查看更多评论'}}