摘要:PHP8已经正式发布3个多月了,这对PHP来说是一个重大版本,这个版本中有很多新功能,例如联合类型、命名参数、Match表达式、Nullsafe空安全运算符、类的反射...
PHP8已经正式发布3个多月了,本想早早研究一下新版本的特性,不过近期太忙了,这几天才抽空研究了一下。
由于重大更改,您需要在代码中进行一些更改才能在 PHP8 中运行。但是,如果您已经跟上最新版本,升级应该不会太难,因为大多数重大更改以前在 PHP7 版本中已弃用。
1.联合类型
考虑到 PHP 动态语言类型的特性,现在很多情况下,联合类型都是很有用的。联合类型是两个或者多个类型的集合,表示可以使用其中任何一个类型。
function show(int|string $a):int|string{ var_dump($a); return 5; } echo show('yzmcms');
请注意,联合类型中不包含void,因为void表示的含义是 “根本没有返回值”,另外PHP7.1支持了null类型,但已被PHP8中的?代替,例如:
//PHP7中的写法 function show(string|null $a){ var_dump($a); } //PHP8中的写法: function show(?string $a){ var_dump($a); }
2.命名参数
命名参数允许您通过指定值名称将值传递给函数,这样您就不必考虑它们的顺序,还可以跳过可选参数!
function foo(string $a, string $b, ?string $c = null, ?string $d = null) { var_dump($a); var_dump($b); var_dump($d); } foo( b: 'value b', a: 'value a', d: 'value d', );
3.Match表达式
与switch比较类似,你可以称它为switch表达式的大哥:match可以返回值,不需要break语句,可以组合条件,使用严格的类型比较,并且不执行任何类型的强制。
PHP7中的写法:
$statusCode = 500; switch ($statusCode) { case 200: case 300: $message = null; break; case 400: $message = 'not found'; break; case 500: $message = 'server error'; break; default: $message = 'unknown status code'; break; } var_dump($message); //server error
PHP8中的写法:
$statusCode = 500; $message = match ($statusCode) { 200, 300 => null, 400 => 'not found', 500 => 'server error', default => 'unknown status code', }; var_dump($message); //server error
4. 构造函数属性提升
PHP7中的写法:
class user{ public string $name; public string $email; public function __construct(string $name, string $email) { $this->name = $name; $this->email = $email; } public function get_attribute(){ var_dump($this->name); var_dump($this->email); } } $test = new user('yuanzhimeng', 'yzmcms@qq.com'); $test->get_attribute();
PHP8中的写法:
class user{ public function __construct(public string $name, public string $email) { } public function get_attribute(){ var_dump($this->name); var_dump($this->email); } } $test = new user('yuanzhimeng', 'yzmcms@qq.com'); $test->get_attribute();
5.Nullsafe空安全运算符
常用于类中属性和方法返回值.
?->
如果全等于NULL则断开并返回NULL,如果不全等于NULL则往后继续执行,这个特性会非常高效的解决代码的冗余。
在PHP7中,有时会存在类属性多条件的判断,如下代码:
class Person{ public $user; public $country; public function __construct(){ $this->user = $this; $this->country='yes'; } public function getAddress(){ return $this; } } $session=new Person(); if($session!==null){ $user = $session->user; if($user!==null){ $address = $user->getAddress(); if($address!=null){ $country = $address->country; if($country!==null){ var_dump($country); } } } }
以上代码返回结果为string(3) "yes"
但是在PHP8中就完美的解决了这种代码冗余的问题:
class Person{ public $user; public $country; public function __construct(){ $this->user = $this; $this->country='yes'; } public function getAddress(){ return $this; } } $session=new Person(); echo $session?->user?->getAddress()?->country;
6. Reflection反射
反射类的 3 个方法签名已变更:
ReflectionClass::newInstance($args); ReflectionFunction::invoke($args); ReflectionMethod::invoke($object, $args);
现在已变成:
ReflectionClass::newInstance(...$args); ReflectionFunction::invoke(...$args); ReflectionMethod::invoke($object, ...$args);
升级指南指定,如果要扩展这些类,并且仍想同时支持 PHP 7 和 PHP 8,则允许以下签名:
ReflectionClass::newInstance($arg = null, ...$args); ReflectionFunction::invoke($arg = null, ...$args); ReflectionMethod::invoke($object, $arg = null, ...$args);
7.注释
方法注释使用:
/** * this is show function */ function show($name) { echo $name; }
类注解类使用:
$ref = new ReflectionFunction("show"); echo $doc = $ref->getDocComment(); #[Attribute(Attribute::TARGET_CLASS)] class MyAttr{ public function __construct($name, $value) { echo "$name,$value"; } } #[MyAttr("api","http://www.yzmcms.com/api")] class Person{} $ref = new ReflectionClass("Person"); $ref->getAttributes("MyAttr")[0]->newInstance();
网友评论:
学到了学到了
2021-04-08 20:30:27 回复
网友评论:
满满的干货,收藏了
2021-03-20 21:17:45 回复