?array 是 PHP 7.1 运行时强制校验的类型约束,接受数组或 null,拒绝 false、0、'' 等假值;不加 strict_types=1 也会抛 TypeError,但加了可杜绝弱类型绕过;它不支持嵌套可空(如 ?array<?string>),且与 iterable 不兼容。

PHP 7.1 的 ?array 类型声明不是语法糖,而是运行时强制校验的类型约束——不加 declare(strict_types=1) 也能触发 TypeError,但加了才能堵死弱类型绕过漏洞。
为什么 ?array 比 array + is_null() 更可靠
直接写 array $items 时传入 null 会立刻抛出 Fatal error: Uncaught TypeError;而用 ?array $items 后,null 是合法输入,无需前置判断。但很多人误以为“只要加了问号就万事大吉”,其实漏掉了关键点:
-
?array不接受false、0、''或对象——这些值仍会触发TypeError - 若函数内部对
$items做了foreach,必须先判空,否则foreach(null as ...)会报Warning: Invalid argument supplied for foreach() - IDE 和静态分析工具(如 PHPStan)只在
?array下才推导出“该变量可能为null”,从而提醒你补if ($items !== null)
?array 在数据库查询结果处理中的典型误用
ORM 或原生 PDO 查询返回 null 表示“无记录”,但开发者常把 fetch() 结果直接塞进 ?array 参数,却忘了 fetch() 可能返回 false(失败)或 array(成功),而 false 不是 null,也不符合 ?array 要求。
- 正确做法:用
fetch(PDO::FETCH_ASSOC)并显式转null:$row = $stmt->fetch() ?: null; - 错误写法:
processUser($stmt->fetch());—— 若查询失败,fetch()返回false,直接炸 - 更安全的封装:
function fetchOrNull(PDOStatement $stmt): ?array { return $stmt->fetch(PDO::FETCH_ASSOC) ?: null; }
和 iterable 混用时的类型陷阱
iterable 能接数组和 Traversable 对象,?array 只认数组和 null,两者语义不同,不能互换。常见错误是把一个声明为 iterable $data 的函数,强行传给接收 ?array $data 的下游函数。
立即学习“PHP免费学习笔记(深入)”;
- 传
Generator给?array参数 →TypeError: Argument must be of type array|null - 想兼容两者?改用
iterable声明,并在内部用is_array($data) ? $data : iterator_to_array($data) - 性能注意:把
Generator转成数组会一次性加载全部数据,大数据流场景慎用
最易被忽略的是:PHP 7.1 的 ?array 不支持嵌套可空,比如 ?array<?string> 是非法语法——类型系统不递归解析问号,所有元素级空值检查仍得靠手动 array_map 或循环内判空。



















