PHP8 新特性总结(一)

袁志蒙 2909次浏览

摘要: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();


随机内容

表情

共2条评论
  • 网友评论:

    学到了学到了

    2021-04-08 20:30:27 回复

    点击加载
  • 网友评论:

    满满的干货,收藏了

    2021-03-20 21:17:45 回复

    点击加载