003. PHP 8.1 更新类相关:Readonly 属性和 Final 类常量
说明
大家好,这个视频将演示 PHP 8.1 两个类相关的新特性, readonly 类属性和 final 类常量。
Readonly 只读属性
1. 构建器初始化
readonly 属性初始化只可以发生在构建函数 (__construct) 里,或者类内部方法:
<?php
class User {
public readonly int $uid;
public function __construct(int $uid) {
$this->uid = $uid;
}
}
$user = new User(42);
dd($user);
2. 只能初始化一次
只读属性只允许初始化一次,修改 readonly 属性会报错:
$user->uid = 1;
Fatal error: Uncaught Error: Cannot modify readonly property User::$uid in
初始化多次
如果 readonly 属性没有初始化,而是在内部方法中初始化:
class Article {
public readonly int $aid;
public function setArticleID(int $aid) {
$this->aid = $aid;
}
}
$article = new Article();
$article->setArticleID(42);
var_dump($article->aid);
内部方法赋值时允许的,但是多次调用:
class Article {
public readonly int $aid;
public function setArticleID(int $aid) {
$this->aid = $aid;
}
}
$article = new Article();
$article->setArticleID(42);
$article->setArticleID(12);
var_dump($article->aid);
就会报错:
Fatal error: Uncaught Error: Cannot modify readonly property Article::$aid
3. 只能类内部初始化
未初始化的属性,作为对象属性赋值:
class Article {
public readonly int $aid;
}
$article = new Article();
$article->aid = 9;
也会报错:
Fatal error: Uncaught Error: Cannot initialize readonly property Article::$aid from global scope
4. 构建器属性
另外 PHP 8.0 的构建器属性功能,也支持 readonly 属性;
class User {
public function __construct(public readonly int $uid) {}
}
以上等于下面代码:
class User {
public readonly int $uid;
public function __construct(int $uid) {
$this->uid = $uid;
}
}
final 类常量
(使用命令行 PHP 解析器)
PHP 的类常量是可以通过继承来修改:
<?php
class Foo {
public const TEST = '1';
}
class Bar extends Foo {
public const TEST = '2';
}
// "2"
dd(Bar::TEST);
如果加上 final 关键词:
class Foo {
final public const TEST = '1';
}
会报错:
FatalError
Cannot use 'final' as constant modifier
接口实现也无法对常量进行修改
interface Template {
final public const SUFFIX = '.blade.php';
}
class WorkingTemplate implements Template {
const SUFFIX = '.tpl';
}
会报错:
Fatal error:
WorkingTemplate::SUFFIX cannot override final constant Template::SUFFIX
不能对 private 的类常量使用 final 关键词:
<?php
class Foo {
final private const TEST = '1';
}
会报错:
Fatal error:
Private constant Foo::TEST cannot be final as it is not visible to other classes