覆盖PHP文档块/方法注释而不重载(PhpStorm自动完成)



这是一个关于 PhpStorm(可能还有其他 IDE)与 PHP 文档块中的自动完成行为的问题。

我必须在我的应用程序中分组类。首先,各种产品(CarProduct,FoodProduct等)都有单独的类,它们都继承自BaseProduct,以及单个合约(CarContract,FoodContract等)的对应物,它们都继承自BaseContract。

<?php
class BaseContract
{
/** @var BaseProduct */
private $product;
/**
* @return BaseProduct
*/
public function getProduct()
{
return $this->product;
}
}

现在我有一个CarContract的实例,我想获取一些CarProduct特定的信息:

<?php
/* PhpStorm thinks, this is BaseProduct */
$product = $carContract->getProduct();
/* hence, getSpeed() is not available for PhpStorm */
$product->getSpeed();

自动完成功能无法按我所希望的方式工作。有两种解决方法,但都不好:

  1. 在子类中重载getProduct(),只是更新了@return文档块
  2. 在我访问汽车合约产品的所有位置添加/** @var CarProduct $product */

是否有一种"通常"的方法来解决这样的事情,或者我的解决方法是唯一的解决方案?

PhpStorm 并不真正允许/不支持执行以下操作:在其他地方定义相同的命名类,并将其用作覆盖真实类定义的参考。你可以这样做..但是 IDE 会用"同一类的多个定义"发出警告,并且可能会引入一些奇怪的行为/意外的警告......

这是一张要求此类功能的票证:https://youtrack.jetbrains.com/issue/WI-851 - 观看它(星号/投票/评论)以获得任何进度的通知。


你的选择是:你可以使用@var在本地(局部变量)提供正确的类型提示——你已经知道了,这是你首先想到的:

<?php
/** @var CarProduct $product */
$product = $carContract->getProduct();
$product->getSpeed();

另一种可能的方法:而不是覆盖实际方法..你可以尝试做同样的事情,但使用@methodPHPDoc - 将处理你的代码:

<?php
/**
* My Car Product class
* 
* @method CarProduct getProduct() Bla-bla optional description
*/
class CarContract extends BaseContract ...

最新更新