类属性从PHP 7.4开始提供,允许在类的属性添加类型。支持可用的类型
bool
int
float
string
array
iterable
object
? (nullable)
self & parent
Classes & interfaces
属性类型对于业务非常友好,因为一个好的封装,通常属性只会用到一种类型,例如封装一个人:
class people
{
public string $name;
public int $age;
}
对于$people->name
人的名称,只能是字符串,年龄 age
只能是数字,无论业务怎么变化,他们的类型是不需要也不允许变化的。
未初始化
$people = new people();
var_dump($people->name);
如果属性添加了类型,但是使用的前没有赋值,php会直接报错;如果name不是一个必要初始的参数,类型可以改为:?string
,这样使用就不会报错
Fatal error: Uncaught Error: Typed property people::$name must not be accessed before initialization in ……
如果 name 没声明类型,那么 $people->name = nill
,如果未初始化,需要判断是否初始化,可以使用 isset()
函数
$people = new people();
var_dump(isset($people->name)); // false
类型约束和自动转换
查看声明类型的属性,当赋值多种类型值时,会怎么变化
$people = new people();
echo "<br>";
$people->name = "张三";
$people->age = 123;
var_dump($people);
echo "<br>";
$people->name = true;
$people->age = true;
var_dump($people);
echo "<br>";
$people->name = 123;
$people->age = "字符串";
var_dump($people);
echo "<br>";
输出
object(people)#1 (2) { ["name"]=> string(6) "张三" ["age"]=> int(123) }
object(people)#1 (2) { ["name"]=> string(1) "1" ["age"]=> int(1) }
Fatal error: Uncaught TypeError: Typed property people::$age must be int, string used in
显然,在赋值其他不同类型值时候,php会在写入时会进行类型验证,并且在不丢失精度下自动完成。
而 string=>int
会直接报错,可见不是简单 (int)$string
强制转换,像复合数据类型、特殊数据类型都是不可以转换的
能自动转换不会报错的类型(标量数据类型)
boolean => int
boolean => float
boolean => string
int => boolean
int => float
int => string
float => int
float => string
float => boolean
string => boolean
禁用转换
如果不需要自动转换,可以通过声明严格类型,禁用转换
declare(strict_types=1);