PHP 8.0 不支持原生泛型,但可通过联合类型(如 int|string|float)配合 PHPDoc @template 注释模拟泛型行为,供静态分析工具推断类型,运行时仅校验联合类型。

PHP 8.0 本身不支持原生泛型(如 TypeScript 或 Java 中的 <T>),所以严格来说,它没有“联合类型与泛型结合使用”的语法机制。但开发者常通过模拟泛型 + 联合类型的方式,在函数签名、文档注释和静态分析层面提升类型表达能力与安全性。
为什么不能直接写泛型?
PHP 8.0 的类型系统仍以运行时类型检查为主,缺乏编译期泛型推导能力。像 function map<t>(array $arr, callable $fn): array<T></t> 这类写法在 PHP 中会报语法错误——尖括号泛型语法未被解析器识别。
如何模拟泛型并搭配联合类型?
常见做法是:用联合类型约束输入/输出的“可能范围”,再配合 PHPDoc 注释声明泛型语义,供 IDE 和静态分析工具(如 PHPStan、Psalm)理解。
-
用联合类型限定实际可接受的类型组合:例如函数支持处理整数或字符串数组,就写
array|int|string或更精确的int[]|string[] -
用 PHPDoc 声明泛型占位符:如
@template T of int|string配合@param T $value和@return T,让工具推断类型流转 -
返回值用联合类型收束可能性:比如一个“查找”函数可能返回对象或 null,就写
MyEntity|null(等价于?MyEntity),而非试图泛化为T|null
实用示例:带类型提示的转换函数
下面是一个真实可用的模式:
立即学习“PHP免费学习笔记(深入)”;
/**
* @template T of int|string|float
* @param T $input
* @return T
*/
function normalizeValue(int|string|float $input): int|string|float
{
if (is_string($input)) {
return trim($input);
}
return $input;
}
这里:
– 参数和返回值用 int|string|float 明确联合类型,保证运行时安全;
– PHPDoc 中的 @template T of ... 告诉 PHPStan:“这个函数保持输入类型不变”,从而支持链式调用推断;
– IDE 在调用 normalizeValue(42) 时能提示返回 int,调用 normalizeValue(" x ") 时提示 string。
注意事项
这种结合方式依赖外部工具,不是语言强制行为:
- PHP 运行时不校验
@template,只校验int|string|float这类实际声明 - 避免在联合类型中混入过于宽泛的类型(如
mixed|object),否则会削弱类型推断效果 - 当需要真正多态结构时,优先考虑接口+具体类实现,比强行模拟泛型更稳定



















