摘要: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 errorPHP8中的写法:
$statusCode = 500;
$message = match ($statusCode) {
200, 300 => null,
400 => 'not found',
500 => 'server error',
default => 'unknown status code',
};
var_dump($message); //server error4. 构造函数属性提升
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 回复