PHP 7.4起属性类型声明为运行时强制校验,须搭配public/private/protected修饰符,不支持var或无修饰符写法;可空类型用?string而非string|null;未初始化的非可空类型属性访问即报错。

PHP 属性类型声明从 7.4 开始可用,不是“可选增强”,而是运行时强制校验——赋值不匹配类型会直接抛出 TypeError,不是警告或静默转换。
属性类型声明必须搭配访问修饰符
不能写 string $name,必须写 public string $name、private int $id 或 protected ?array $items。省略修饰符(比如只写 string $name)在 PHP 7.4+ 是语法错误。
-
var $name是过时写法,不支持类型声明,且已弃用 -
static $count这种静态属性声明也不支持类型,除非加上修饰符和类型,如public static int $count -
readonly属性必须带类型(如readonly string $slug),且只能在构造函数或初始化时赋值一次
默认值必须是常量且符合类型
属性初始化值不能是函数调用、变量、表达式(哪怕看起来是常量),只能是字面量或类常量。
- ✅ 合法:
public string $status = 'active';、public int $max = self::DEFAULT_LIMIT; - ❌ 非法:
public string $now = date('Y-m-d');、public array $list = $this->getDefault();、public float $pi = 3.14 + 0.001; - ⚠️ 注意:
public ?string $email = null;合法,但public string $email = null;会报错——类型不兼容
可空类型(?Type)和联合类型不能混用
PHP 7.4 支持 ?string,但不支持 string|null(那是 PHP 8.0+ 的联合类型语法)。如果项目还在用 7.4,别写 string|null $name,它会解析失败。
立即学习“PHP免费学习笔记(深入)”;
- ✅ 7.4 正确写法:
public ?string $name; - ❌ 7.4 报错写法:
public string|null $name;(Parse error: syntax error) - ⚠️ 即使你用的是 PHP 8.0+,
?string和string|null行为一致,但 IDE 和静态分析工具对前者识别更稳定 - 数组类型要写
array或string[](后者是 PHP 7.4+ 支持的简写,但string[]在反射中仍被识别为array)
类型未初始化就访问会触发致命错误
带类型的属性(如 public int $id)如果没在构造函数里赋值,也没设默认值,首次读取时就会抛出 Error:“Typed property must not be accessed before initialization”。
- 这意味着不能依赖“未设置即为 null”的旧习惯;
public ?int $score可以不初始化,但public int $score必须显式赋值 - 常见坑:在
__construct()里漏掉某个 typed 属性的赋值,测试时可能不触发,但实际请求中一读就崩 - 安全做法:所有非可空 typed 属性,都在构造函数参数中强制传入,或在构造函数体里明确初始化
最易被忽略的一点:类型声明不会自动校验 setter 方法里的赋值——如果你写了 public function setName(string $name): void { $this->name = $name; },那没问题;但若漏掉类型提示,比如 public function setName($name),再往里塞个数组,$this->name 仍会触发 TypeError,但错误发生在赋值行,而非参数传入时。所以类型声明和方法参数类型提示最好一起上。



















