联合类型(Union Types)
在PHP7中,我们在强制函数返回类型时是这样做的
function create() : bool
那么在PHP8中你可以使用多种预测类型
function create() : bool|string
当然在传参时也可以这样做
function create(bool|string $userId)
Attributes(注解)
这个叫做注释,对于以前的PHP来说,注释中的@param和@see毫无意义,整个这一段会保存为一个函数/方法的一个叫做doc_comment的字符串。
/**
* @param Foo $argument
* @see https:/xxxxxxxx/xxxx/xxx.html
*/
function dummy($Foo) {}
而Attributes呢,其实就是把“注释”升级为支持格式化内容的“注解”
<?php
#[
Params("str", "argument"),
See("https://xxxxxxxx/xxxx/xxx.html")
]
function dummy($str): mixed
{
return $str;
}
# 现在获取这段注解则可以使用
$ref = new ReflectionFunction("dummy");
var_dump($ref->getAttributes("See")[0]->getName());
var_dump($ref->getAttributes("See")[0]->getArguments());
类中的成员变量
在PHP8之前,我们一般会这样定义一个类,首先要设置成员变量,然后在构造或者某一个方法为它赋值。
class User{
public $username;
public $phone;
public $sex;
public function __contruct(
$username,$phone,$sex
){
$this->username = $username;
$this->phone = $phone;
$this->sex = $sex;
}
}
但是 PHP8上我们可以这样写
<?php
class User{
public function __construct(
public string $username = "lin",
public string $phone = "130",
public string $sex = "男"
){
}
}
命名参数
<?php
/**
* @param $name
* @param $controller
* @param $model
* @return string
*/
function role($name, $controller="UserController", $model): string
{
return $name.$controller.$model;
}
echo role("user/login","LoginController","login").PHP_EOL;
echo role(name:"user/login",controller:"MemberController", model:"login").PHP_EOL;
echo role(name: "user/login", model: "login").PHP_EOL;
Match 表达式
match是PHP8中新增的关键字(即无法再做类名),其作用与switch有点相似,用于变量的值转换与赋值,使用如下
<?php
$input = true;
$result = match($input) {
"true" => 1,
"false" => 0,
"null" => NULL,
default => "def",
};
var_dump($result);
static 返回类型
虽然已经可以返回 self,但是考虑到 PHP 具有动态类型的性质,PHP 8 中支持 static 返回类型将更加高效
<?php
class Test {
public $_name = 'test';
public function getStatic(): static {
return new static();
}
}
$obj = new Test();
var_dump($obj->getStatic()->_name); //输出: string(4) "test"
允许对对象使用 ::class
一个很小但是很有用的新特性:现在可以在对象上使用 :: class ,而不必在对象上使用 get_class() ,它的工作方式跟 get_class() 相同。
$foo = new Foo();
var_dump($foo::class);
省去异常变量
在 PHP 8 之前,无论何时你想要捕获一个异常,你都需要先将其存储到一个变量中,不管这个变量你是否会用到。通过 Non-capturing catches 你可以忽略变量,所以替换下面的代码:
try {
// Something goes wrong
} catch (MySpecialException $exception) {
Log::error("Something went wrong");
}
你现在可以这么做:
try {
// Something goes wrong
} catch (MySpecialException) {
Log::error("Something went wrong");
}
新增 str_contains() 函数
一个字符串是否包含另一个字符串
if (str_contains('string with lots of words', 'words'))
新增 str_starts_with() 和 str_ends_with() 函数
判断开始和结束的字符串
str_starts_with('haystack', 'hay'); // true
str_ends_with('haystack', 'stack'); // true
一致的类型错误
之前版本在出现类型错误时,PHP 中的用户定义函数已经会抛出 TypeErrors,但是内部函数不会这么做,而是发出警告并返回 null。从 PHP 8 开始,内部函数的行为已变得和用户定义函数一致。
WeakMap(弱映射)
对象可以作为键值对中的键。
当对象没有被引用时,会被当做垃圾回收掉。
对象当做键时,如果没有被引用,也许会被回收,也许不被回收,Map中的对象作为键时不会被回收。WeakMap中的对象作为键时,如果没有被引用就会被回收。