PHP 8.0+ 联合类型

举报
林欣 发表于 2025/09/23 11:49:16 2025/09/23
【摘要】 在 PHP 8.0 及以上版本中,联合类型(Union Types) 是一个重要特性,它允许一个参数、返回值或属性声明为多个可能的类型。这为模拟泛型行为提供了更强的类型安全性。 1. 联合类型基础联合类型用 | 分隔多个类型,表示值可以是其中任意一种类型。 示例:函数参数与返回值function printId(int|string $id): void { echo "ID: " ....

在 PHP 8.0 及以上版本中,联合类型(Union Types) 是一个重要特性,它允许一个参数、返回值或属性声明为多个可能的类型。这为模拟泛型行为提供了更强的类型安全性。


1. 联合类型基础

联合类型用 | 分隔多个类型,表示值可以是其中任意一种类型。

示例:函数参数与返回值

function printId(int|string $id): void {
    echo "ID: " . $id;
}

printId(100);      // 合法(int)
printId("abc123"); // 合法(string)
printId([]);       // 报错:TypeError

示例:类属性

class User {
    public int|string $id;
}

$user = new User();
$user->id = 1;      // 合法
$user->id = "abc";  // 合法
$user->id = [];     // 报错:TypeError

2. 联合类型与泛型结合

虽然 PHP 没有原生泛型,但可以通过联合类型 + @template(PHPDoc)模拟泛型行为。

示例:模拟泛型函数

/**
 * @template T
 * @param T $value
 * @return T
 */
function identity(int|string|array $value): int|string|array {
    return $value;
}

$num = identity(42);      // 返回 int
$str = identity("foo");   // 返回 string
$arr = identity([1, 2]);  // 返回 array

示例:泛型集合类

/**
 * @template T
 */
class Box {
    /** @var T */
    private mixed $value;

    /**
     * @param T $value
     */
    public function __construct(mixed $value) {
        $this->value = $value;
    }

    /**
     * @return T
     */
    public function getValue(): mixed {
        return $this->value;
    }
}

$intBox = new Box(42);      // Box<int>
$strBox = new Box("foo");   // Box<string>

3. 联合类型的高级用法

(1) 可空类型(Nullable Types)

PHP 8.0 之前用 ?Type 表示可空,现在也可以用联合类型:

function greet(?string $name): void {
    echo "Hello, " . ($name ?? "Guest");
}

// 等价于:
function greet(string|null $name): void { /* ... */ }

(2) 联合类型与 null 结合

function findUser(int $id): User|null {
    // 返回 User 或 null
}

(3) 联合类型与 false(PHP 8.1+)

PHP 8.1 允许 false 作为联合类型的一部分(常用于兼容 false 返回值):

function strpos(string $haystack, string $needle): int|false {
    // 返回 int 或 false
}

4. 联合类型的运行时检查

PHP 不会自动检查联合类型,但可以手动验证:

function processInput(int|string $input): void {
    if (is_int($input)) {
        echo "Integer: " . $input;
    } elseif (is_string($input)) {
        echo "String: " . $input;
    } else {
        throw new TypeError("Invalid type");
    }
}

5. 联合类型 vs. 泛型

特性 联合类型 泛型(如 Java/C#)
类型检查 运行时手动检查 编译时自动检查
适用范围 参数、返回值、属性 类、接口、方法
类型参数 固定几种类型(如 `A B`)
IDE 支持 部分支持 完全支持

6. 最佳实践

  1. 优先使用 PHP 8.0+ 类型系统(联合类型、mixednever)。
  2. 结合 PHPDoc 的 @template 模拟泛型,提升 IDE 类型提示。
  3. 避免过度使用联合类型,否则可能导致代码可读性下降。
  4. 运行时手动验证类型(如 is_int()),确保安全性。

总结

  • PHP 8.0+ 的联合类型允许一个变量接受多种类型,但不是真正的泛型
  • 结合 PHPDoc 的 @template 可以模拟泛型行为。
  • 对于复杂场景,可以考虑使用 静态分析工具(如 Psalm、PHPStan) 增强类型检查。

如果需要更强的泛型支持,可以关注 PHP RFC 进程 或使用 Hack 语言(Facebook 的 PHP 衍生语言)

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。