PHP 7.1+可空类型仅适用于用户自定义函数的参数和返回值声明,不支持内置函数、类属性(PHP 7.1中语法错误)或签名覆写;必须启用strict_types=1,且默认值须显式为null。

PHP 7.1+ 的可空类型(Nullable Types)不能用于内置函数的声明或修改——这是关键前提。内置函数(如 strlen()、array_merge()、json_decode() 等)由 Zend 引擎实现,其签名在 PHP 源码中硬编码,用户无法用 ?string、?array 等语法去“重新声明”或“覆盖”它们。
你真正能使用可空类型的场景,仅限于你自己定义的函数、方法和返回值声明。
✅ 正确做法:在自定义函数中声明可空类型
可空类型通过 ?Type 语法支持,适用于:
- 函数参数类型声明
- 函数返回值类型声明
且必须满足:
立即学习“PHP免费学习笔记(深入)”;
- 启用严格类型模式:
declare(strict_types=1);(否则类型提示仅作运行时警告,不强制) - 默认值若存在,必须显式为
null(例如?int $id = null,不能写?int $id = 0)
示例 1:可空参数 + 可空返回值
<?php
declare(strict_types=1);
function safeCount(?array $items): ?int {
return $items === null ? null : count($items);
}
var_dump(safeCount(['a', 'b'])); // int(2)
var_dump(safeCount(null)); // NULL
// safeCount('not array'); // TypeError(被严格模式拦截)示例 2:可空对象参数(如可选依赖)
class Logger {}
class NullLogger extends Logger {}
function logMessage(?Logger $logger, string $msg): void {
if ($logger !== null) {
echo "[LOG] $msg\n";
} else {
echo "[NULL LOGGER] $msg\n";
}
}❌ 常见误解澄清
不能给内置函数加可空类型提示
比如function strlen(?string $str): ?int { ... }是非法的,也毫无意义——strlen()本身就不接受null,传入会直接报TypeError(PHP 7.1+ 默认行为)。不能用
?修改已有函数签名
PHP 不支持函数重载或签名覆写。?array只在你function定义时生效。类属性不支持
?Type(PHP 7.1 不支持)private ?string $name;在 PHP 7.1 中是语法错误,该语法直到 PHP 7.4 才支持(且需写作string|null,不支持?string属性声明)。
? 补充:如何安全调用可能返回 null 的内置函数?
虽然不能改内置函数,但可以封装一层:
function jsonDecodeSafe(?string $json): ?array {
if ($json === null) {
return null;
}
$data = json_decode($json, true);
return is_array($data) ? $data : null;
}这样,你对外暴露的是带可空语义的接口,内部桥接原生函数。
总结要点
- 可空类型是用户定义函数的类型声明工具,不是给内置函数“打补丁”的机制
- 用
?Type明确表达「这个值可能根本不存在」,比用mixed或默认值更安全、更清晰 - 配合
strict_types=1和null默认值,才能发挥完整约束力 - 处理外部数据(API、DB、配置)时,优先用
?array、?string、?int声明输入/输出,提前拦截非法值



















