如何用PHPDoc实现QueryBuilder返回子类数组以获取IDE自动补全?
实现SalesforceAccount查询结果的IDE自动补全
问题场景
现有代码结构如下:
class QueryBuilder { public function get(): SalesforceObject[] { ... } } class SalesforceObject { public function query(): QueryBuilder { return new QueryBuilder(); } } class SalesforceAccount extends SalesforceObject { public string $Id; public string $Name; } // 使用示例 $accounts = SalesforceAccount::query()->get(); foreach($accounts as $account) { $account-> // 这里希望IDE自动补全Id、Name等属性 }
需求:无需在foreach内添加文档块,也不用为每个实体类创建专属的QueryBuilder子类,仅通过PHPDoc实现$account的属性自动补全。
解决方案
通过PHPDoc泛型和静态方法注解可以实现,参考Laravel Eloquent的实现思路,具体修改如下:
1. 给QueryBuilder添加泛型注解
修改QueryBuilder的PHPDoc,声明它支持关联具体的实体类类型:
/** * @template T of SalesforceObject */ class QueryBuilder { /** * @return T[] */ public function get(): array { ... } }
这里用@template定义泛型参数T,限制为SalesforceObject的子类,然后get()方法返回T[]类型,替代原来的SalesforceObject[]。
2. 给SalesforceAccount添加静态@method注解
在SalesforceAccount类上添加@method注解,指定静态query()方法返回绑定了当前类的QueryBuilder实例:
/** * @method static QueryBuilder<SalesforceAccount> query() */ class SalesforceAccount extends SalesforceObject { public string $Id; public string $Name; }
如果有多个实体类,只需要在每个子类上添加对应的@method注解即可,无需修改父类或QueryBuilder。
3. (可选)优化父类的query方法
如果希望父类的query()方法也能自动推导子类类型,可以给父类的query()方法添加泛型返回注解:
class SalesforceObject { /** * @return QueryBuilder<static> */ public function query(): QueryBuilder { return new QueryBuilder(); } }
这里用static关键字表示返回的QueryBuilder绑定当前调用类的类型,这样子类无需单独写@method注解也能自动推导,更简洁。
效果说明
修改后,IDE会自动识别SalesforceAccount::query()->get()返回的是SalesforceAccount[]类型,在foreach循环中,$account会被推断为SalesforceAccount实例,直接支持Id、Name等属性的自动补全,无需额外添加文档块。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

