如何让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
相关产品推荐
相关产品推荐

