新增特性如下
枚举
PHP < 8.1
class Status
{
const DRAFT = 'draft';
const PUBLISHED = 'published';
const ARCHIVED = 'archived';
}
function acceptStatus(string $status) {…}
PHP 8.1
enum Status
{
case Draft;
case Published;
case Archived;
}
function acceptStatus(Status $status) {…}
只读属性
PHP < 8.1
class BlogData
{
private Status $status;
public function __construct(Status $status)
{
$this->status = $status;
}
public function getStatus(): Status
{
return $this->status;
}
}
PHP 8.1
class BlogData
{
public readonly Status $status;
public function __construct(Status $status)
{
$this->status = $status;
}
}
一流的 Callable Syntax
PHP < 8.1
$foo = [$this, 'foo'];
$fn = Closure::fromCallable('strlen');
PHP 8.1
$foo = $this->foo(…);
$fn = strlen(…);
初始化器中的新内容
PHP < 8.1
class Service
{
private Logger $logger;
public function __construct(
?Logger $logger = null,
) {
$this->logger = $logger ?? new NullLogger();
}
}
PHP 8.1
class Service
{
private Logger $logger;
public function __construct(
Logger $logger = new NullLogger(),
) {
$this->logger = $logger;
}
}
对象现在可以用作默认参数值、静态变量和全局常量,以及属性参数。
这有效地使使用嵌套属性成为可能。
PHP < 8.1
class User
{
/**
* @Assert\All({
* @Assert\NotNull,
* @Assert\Length(min=5)
* })
*/
public string $name = '';
}
PHP 8.1
class User
{
#[\Assert\All(
new \Assert\NotNull,
new \Assert\Length(min: 6))
]
public string $name = '';
}
纯交集类型
PHP < 8.1
function count_and_iterate(Iterator $value) {
if (!($value instanceof Countable)) {
throw new TypeError('value must be Countable');
}
foreach ($value as $val) {
echo $val;
}
count($value);
}
PHP 8.1
function count_and_iterate(Iterator&Countable $value) {
foreach ($value as $val) {
echo $val;
}
count($value);
}
当一个值需要同时满足多个类型约束时,使用交集类型。
目前无法将交集和联合类型混合在一起,例如A&B|C.
从不返回类型
PHP < 8.1
function redirect(string $uri) {
header('Location: ' . $uri);
exit();
}
function redirectToLoginPage() {
redirect('/login');
echo 'Hello'; // <- dead code
}
PHP 8.1
function redirect(string $uri): never {
header('Location: ' . $uri);
exit();
}
function redirectToLoginPage(): never {
redirect('/login');
echo 'Hello'; // <- dead code detected by static analysis
}
与声明的函数或方法never类型表明它不会返回一个值,要么抛出一个异常,或与通话结束脚本的执行die(),exit(),trigger_error(),或者类似的东西。
最终类常量
PHP < 8.1
class Foo
{
public const XX = “foo”;
}
class Bar extends Foo
{
public const XX = “bar”; // No error
}
PHP 8.1
class Foo
{
final public const XX = “foo”;
}
class Bar extends Foo
{
public const XX = “bar”; // Fatal error
}
可以声明 final 类常量,以便它们不能在子类中被覆盖。
显式八进制数字表示法Doc
PHP < 8.1
016 === 16; // false because `016` is octal for `14` and it's confusing
016 === 14; // true
PHP 8.1
0o16 === 16; // false — not confusing with explicit notation
0o16 === 14; // true
Fibers
PHP < 8.1
$httpClient->request('https://example.com/')
->then(function (Response $response) {
return $response->getBody()->buffer();
})
->then(function (string $responseBody) {
print json_decode($responseBody)['code'];
});
PHP 8.1
$response = $httpClient->request('https://example.com/');
print json_decode($response->getBody()->buffer())['code'];
对字符串键控数组的数组解包支持
PHP < 8.1
$arrayA = ['a' => 1];
$arrayB = ['b' => 2];
$result = array_merge(['a' => 0], $arrayA, $arrayB);
// ['a' => 1, 'b' => 2]
PHP 8.1
$arrayA = ['a' => 1];
$arrayB = ['b' => 2];
$result = ['a' => 0, …$arrayA, …$arrayB];
// ['a' => 1, 'b' => 2]
你相信光吗
大神,留步,别动,打劫!