随着PHP8的发布,作为动态类型语言的PHP也有了更大的进步。 此处浅谈一下PHP8中的类型定义以及几个新特性 本文仅介绍重点,详细内容可以参考 PHP 官方。
数据类型 (Data Type)
数据类型 (Data Type) 用来表示储存的数据类型,也称为型别。
数据类型 | 说明 | 数据范例 |
---|---|---|
bool | 布尔 | true, false |
int | 整型 | 1, 0, -1, … |
float | 浮点数 | 0.1, -0.2, … |
string | 字符串 | “hello world!” |
array | 数组 | [“hello”, “world”, 2, 0.1] |
object | 对象 | new Example(), (object) [‘hello’ => ‘world’] |
resource | 资源 | 资源 |
null | 空值 | null |
Function
语法:(PHP7.0以上)
代码语言:javascript复制function FUNCTION_NAME(VAR_TYPE $VAR_NAME = VAR_DEFAULT_VALUE, ...): RETURN_TYPE{
//do somethings
return $VAR;
}
FUNCTION_NAME:函数名
VAR_TYPE: 自变量
VAR_NAME: 自变量名称
VAR_DEFAULT_VALUE: 自变量默认值,此自变量可以不被传入,不传入时自动采用默认值
RETURN_TYPE: 返回值
Nullsafe operator:加上 ? 表示可能会传 null
另外,可以使用 |null 或者现有的 ? 表示法来表示包含 nullable 的联合体。
代码语言:javascript复制function myStrValue(string|null $a = 'hello'): ?string {
return $a;
}
echo myStrValue();//hello
echo myStrValue(null);//
echo myStrValue('你好');//你好
function myStrConcat(?string $a = 'hello', string $b = null): string {//默认值为null亦可传null
return $a . $b;
}
echo myStrConcat(); //hello
echo myStrConcat(null); //
echo myStrConcat(null, 'world'); //world
echo myStrConcat('你好', '世界'); //你好世界
补充说明:
- PHP 属于动态类型程序语言,允许所有变量可以不用带入数据类型,改由系统自动判别。但动态类型程序语言最令人诟病的地方就是过度方便新手开发人员 (可以不理会类型),而苦了 Web Server (需要判别类型),也容易造成开发人员因为类型问题产生的语意BUG。
- 开发人员预先定义好数据类型,可以有效增加程序运行效率。PHP 7.0 起,允许在 function 内约束自变量类型、返回值类型。PHP8起,允许在 function 内约束复合类型。
范例
范例:没有任何自变量也不回传任何东西
代码语言:javascript复制/**
* myFirstFunc
* @return void
*/
function myFirstFunc(): void{
echo 'hellowrold';
return; //回传 void 时,写 return 的话,后面不可以带返回值。也可以不写 return
}
myFirstFunc(); // helloworld
范例:两字符串相加,回传字符串类型,第二个自变量预设 null,表示可以不传入。
代码语言:javascript复制/**
* my string concat
* @param string $a string A
* @param string $b string B
* @return string
*/
function myStrConcat(string $a, string $b = null): string{
return $a . $b;
}
echo myStrConcat('hello', 'world'); // helloworld
echo myStrConcat('helloworld'); // helloworld
范例:通过数据库,可能会拿到 null,故返回值需检查 null。
代码语言:javascript复制/**
* get user
* @param int $userId user ID
* @return object|null
*/
function getUser(int $userId): ?object{
//do something
}
范例:复合类型,PHP8后允许自变量、返回值有复合类型。
代码语言:javascript复制/**
* getUsers
* @param int|array $userIds user IDs
* @return array|null
*/
function getUsers(int|array $userIds): ?array{
//do something
}
范例:mixed = array|bool|callable|int|float|null|object|resource|string
(PHP中不写类型默认为mixed,例如:function getUsers($userId){}
。)
请注意,mixed也可以用作参数或属性类型,而不仅仅是作为返回类型。
另请注意,由于mixed已包含null,因此不允许使其为空(nullable)。以下代码将触发错误:
代码语言:javascript复制// Fatal error: Mixed types cannot be nullable, null is already part of the mixed type.
function getUsers(mixed $userId): ?mixed {
//do something
}
其他
顺带提一下php8中比较喜欢的几个更新
Match表达式
你可以称它为switch表达式的大哥,match可以返回值,不需要break语句,可以组合条件,并且不执行任何类型的强制。 新的 match 类似于 switch,并具有以下功能:
Match 是一个表达式,它可以储存到变量中亦可以直接返回。
Match 分支仅支持单行,它不需要一个 break; 语句。
Match 使用严格比较。 如下所示:
代码语言:javascript复制$result = match($input) {
0 => "hello",
'1', '2', '3' => "world",
};
$message = match ($statusCode) {
200, 300 => null,
404 => 'not found',
500 => 'server error',
default => 'unknow status code'
}
Throw表达式
throw 从语句更改为表达式,从而有可能在许多新位置引发异常:
代码语言:javascript复制$callable = fn() => throw new Exception();
$triggerError = fn () => throw new MyError();
$foo = $bar['offset'] ?? throw new OffsetDoesNotExist('offset')
$condition || throw new Exception('$condition must be truthy')
&& $condition2 || throw new Exception('$condition2 must be truthy');
用参数名传递参数而不是参数的顺序
代码语言:javascript复制setcookie(
name: 'test',
expires: time() 60 * 60 * 2
);
$data = [
'name' => 'test',
'expires' => time() 60 * 60 * 2
];
setcookie(...$data);
构造器属性提升
代码语言:javascript复制/*
* PHP7
*/
class Point {
public float $x;
public float $y;
public float $z;
public function __construct(
float $x = 0.0,
float $y = 0.0,
float $z = 0.0,
) {
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
}
/*
* PHP8
*/
class Point {
public function __construct(
public float $x = 0.0,
public float $y = 0.0,
public float $z = 0.0,
) {}
}
字符串与数字的比较更符合逻辑
代码语言:javascript复制/*
* PHP7
*/
0 == 'foobar' // true
/*
* PHP8
*/
0 == 'foobar' // false
Nullsafe 运算符
代码语言:javascript复制/*
* PHP7
*/
$country = null;
if ($session !== null) {
$user = $session->user;
if ($user !== null) {
$address = $user->getAddress();
if ($address !== null) {
$country = $address->country;
}
}
}
/*
* PHP8
*/
$country = $session?->user?->getAddress()?->country;
对象获取类名
代码语言:javascript复制$object = new stdClass;
var_dump($object::class); // "stdClass"
static return type
代码语言:javascript复制class Test {
public function withWhatever($whatever): static {
$clone = clone $this;
$clone->whatever = $whatever;
return $clone;
}
}