PHP 7.1 支持函数参数和返回值的可空类型(?Type),但不支持类属性、?void、联合类型(如 ?array|string)及注释模拟;必须启用 strict_types=1 才生效,且默认值只能为 null。

整理 PHP 7.1 可空类型笔记时,需严格区分语法生效范围、版本兼容边界和运行时行为差异,避免把 PHP 8.0+ 的联合类型特性错误归入 7.1,否则后续代码在生产环境(如 CentOS 7 + PHP 7.1.33)中会直接报 Parse Error。
确认可空类型在 PHP 7.1 中的真实能力边界
第一步:打开终端,执行 php -v,确认输出以 PHP 7.1. 开头(如 7.1.33),而非 7.2+ 或 8.x;低于 7.1.0 的任何版本都不支持 ?Type 语法,写即报错。
第二步:新建 test.php,写入 declare(strict_types=1); function foo(?string $s): ?int { return $s ? strlen($s) : null; },然后 php test.php —— 若无报错且能正常运行,说明环境就绪。
第三步:尝试在类属性上写 private ?string $name;,执行后会触发 Fatal error: Syntax error,因为 PHP 7.1 不支持属性声明可空类型,该语法直到 PHP 7.4 才允许(且仍不支持 ? 前缀,须写 string|null)。
立即学习“PHP免费学习笔记(深入)”;
只在允许的位置使用 ?Type
方法一:函数参数声明
直接在参数类型前加 ?,例如 function process(?array $data, ?int $limit = null)。注意:若设默认值,必须显式为 null,写成 ?int $limit = 0 是非法的——默认值必须与可空性一致,即 ?Type $param = null。
方法二:函数返回值声明
在冒号后加 ?Type,例如 function findUser(int $id): ?User。此时若返回 null,不报错;若返回 new StdClass(),则触发 TypeError。
方法三:构造函数参数中配合 null 合并操作符
class Service { public function __construct(?Logger $logger) { $this->logger = $logger ?? new NullLogger(); } } —— 这是 PHP 7.1 中最安全的兜底写法,比手动 is_null() 判空更简洁。
避开常见误写陷阱
不要写 ?void —— PHP 7.1 不允许,void 本身已表示“无返回”,?void 语法无效且解析失败。
不要写 ?array|string —— 这不是联合类型,PHP 7.1 不支持 | 运算符,? 只能修饰单一基础类型或类名;正确写法只能是 ?array 或 ?string,不能混用。
不要依赖注释模拟可空性,例如 /** @param string|null $x */ function bar($x) {} —— 这在 PHP 7.1 运行时不生效,仅对 PHPStan 等静态分析工具有提示作用,实际调用传 int 仍会静默通过,失去类型约束意义。
验证可空行为是否生效
写一个最小测试用例:
function greet(?string $name): string { return $name ?? 'Guest'; }
var_dump(greet(null), greet('Alice'), greet(123));
预期输出前三行正常,最后一行抛出 Fatal error: Uncaught TypeError: Argument 1 must be of type string|null —— 如果没报错,说明 strict_types=1 缺失或未启用,可空类型在非严格模式下完全退化为普通参数,形同虚设。



















