覆盖方法的PHP docblock / annotation而不重载(PhpStorm autocompletion)

时间:2017-03-30 08:16:23

标签: php autocomplete phpstorm docblocks

这是一个关于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 docblocks
  2. 在任何地方添加/** @var CarProduct $product */,我访问CarContract的产品
  3. 是否有一种“通常”的方式来解决这样的问题,或者我的解决方案是唯一的解决方案吗?

1 个答案:

答案 0 :(得分:1)

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

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

您的选择是:您可以使用@var在本地(对于本地变量)提供正确的类型提示 - 您已经知道它并且这是您首先想到的:

<?php

/** @var \CarProduct $product */
$product = $carContract->getProduct();

$product->getSpeed();

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

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