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

如何让PHP静态代码分析器从DTO获取泛型类型,无需传入类名字符串?

问题:让CrudManager的save方法返回DTO对应的具体实体类型

我正在消除易引发人为错误的代码重复,现有架构如下:

  • 使用可生成实体的DTO:
    • 接口CrudDto定义了public function apply(): CrudEntity方法;
    • CreatePersonDto实现CrudDto,其apply()方法返回Person实例;
    • Person继承自CrudEntity。
  • CrudManager类通过save(CrudDto $dto): CrudEntity方法处理DTO;
  • 调用$crudManager->save($dto)会返回该DTO对应的实体,例如传入CreatePersonDto时返回Person,传入CatCreateDto时返回Cat。

我希望CrudManager::save()能明确返回具体的实体类型(如Person、Cat),而非通用的CrudEntity。目前我通过给save()方法传入类名字符串实现了这个效果,但不想让开发者手动指定class-string<T of CrudEntity> $className参数——既然DTO本身就知道要创建的实体类,应该由它主动提供类型信息。

我已经给CrudDto添加了belongsTo(): string方法,返回对应实体的完全限定类名(FQCN),运行时可以强制类型,但静态代码分析器(PHPStan、PHPStorm、Psalm等)无法识别这个类名字符串来自DTO自身。我期望实现类似以下伪代码的效果:

/**
 * @template T of CrudEntity
 * @param class-string<T> $dto::belongsTo()
 */
public function save(CrudDto $dto): CrudEntity;

简单来说,我想让静态分析器知道:如果CreatePersonDto::belongsTo()返回Person::class,那么调用$crudManager->save($personDto)时应该返回Person,而不只是CrudEntity。请问有没有办法不用在save()方法中传入返回类名字符串,就能实现这个需求?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 22:12:35