You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中如何为返回更具体类型的子类编写合规文档?

解决PHP抽象类子类方法更具体类型兼容问题

要让子类的getState/setState使用更具体的标量类型,同时通过Psalm/PHPStan的静态分析,核心是正确利用PHP的**模板泛型(@template)**机制,确保子类与基类的方法签名在参数化后保持兼容。

步骤1:正确定义带模板的抽象基类

基类需要用@template声明一个可替换的类型参数,让方法的参数/返回类型与该模板绑定:

<?php

/**
 * @template TState
 */
abstract class HasState
{
    /**
     * @var TState
     */
    protected $state;

    /**
     * @return TState
     */
    abstract public function getState();

    /**
     * @param TState $state
     */
    abstract public function setState($state);
}

步骤2:子类绑定具体模板类型并实现方法

子类通过@extends指定具体的模板类型,然后重写方法时使用对应的具体类型,此时静态分析工具会识别出这是基类模板实例化后的合法签名:

示例1:状态为string类型的子类

<?php

/**
 * @extends HasState<string>
 */
class StringState extends HasState
{
    public function getState(): string
    {
        return $this->state;
    }

    public function setState(string $state): void
    {
        $this->state = $state;
    }
}

示例2:状态为array类型的子类

<?php

/**
 * @extends HasState<array>
 */
class ArrayState extends HasState
{
    public function getState(): array
    {
        return $this->state;
    }

    public function setState(array $state): void
    {
        $this->state = $state;
    }
}

关键注意事项

  • 必须确保基类的@template声明与方法的类型注解完全绑定:getState返回TState,setState接收TState参数。
  • 子类的@extends必须明确指定具体类型(如string/array),这相当于告诉静态分析工具:“该子类是基类使用TState=string实例化后的版本”。
  • 子类重写方法时的具体类型必须与@extends中指定的模板类型一致,否则仍会触发签名不兼容错误。

这种方式既满足了子类使用具体类型的需求,又符合静态分析工具的类型检查规则,不会出现方法签名不兼容的报错。

内容的提问来源于stack exchange,提问作者Colin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 03:12:44