PhpStorm警告"期望的class1,得到class2"当class2扩展class1时

时间:2016-09-01 14:34:49

标签: php phpstorm phpdoc type-hinting

我使用的是Phalcon Framework,它有模型类:NSArray *a1 = [NSArray arrayWithObjects:[[MyObject alloc] initWithName:@"name"], [[MyObject alloc] initWithName:@"name2"], nil]; NSArray *a2 = [NSArray arrayWithObjects:[[MyObject alloc] initWithName:@"name2"], [[MyObject alloc] initWithName:@"name"], nil]; if ([a1 isEqual:a2]) { NSLog(@"Array match"); } else { NSLog(@"No array match"); } NSSet *s1 = [NSSet setWithArray:a1]; NSSet *s2 = [NSSet setWithArray:a2]; if ([s1 isEqual:s2]) { NSLog(@"Set match"); } else { NSLog(@"No set match"); } (从现在开始仅作为Phalcon\Mvc\Model)。我已经定义了基本域,它扩展了该类,然后每个其他域都扩展了我的基本域,因此Phalcons Model类:

Domain.php:

P\M\Model

DomainA.php:

class Domain extends \Phalcon\Mvc\Model
{
    ...
}

然后我使用存储库管理器获取class DomainA extends Domain { ... } 模型的存储库。所有存储库都具有相同的父级,与Domain类似,后者已定义方法find()

Repository.php:

DomainA

RepositoryA.php:

class Repository
{
    /**
    * Will always return object of classes 
    * which extends Phalcon\Mvc\Model
    *
    * @return Phalcon\Mvc\Model
    */
    public function find()
    {
        ...
        $domain::find();
    }
}

所以,class RepositoryA extends Repository { ... } 现在有来自其父级的方法find(),因为父级不知道他将要返回什么,但是知道所有返回的父级是什么,所以它是类型提示它通过RepositoryA

然后我有一些其他类,它的方法只期望@return对象,它也是DomainA的父对象,我尝试推送那种类型的对象,它工作正常,因为返回的对象来自存储库实际上是一个P\M\Model对象,但是存储库将其注释为DomainA,因此PhpStorm通过消息"预期的DomainA,获得Phalcon \ Mvc \ Model ..."突出显示它。

P\M\Model

我应该如何注释这种东西?提示public function pleaseGiveDomainA(DomainA $obj) { ... } // Works OK but is higlighted in IDE $this->pleaseGiveDomainA($repositoryA->find()); 所有类似@return等域名的情况并不好,因为我们有数百个域名,但在功能上期望父@return DomainA|DomainB|DomainC...不好,因为我们只想确定它是唯一的DomainA中。

感谢。

3 个答案:

答案 0 :(得分:1)

尝试使用界面而不是基础模型。根据我的经验,有时PHPStorm可能会混淆这种复杂的类层次结构。在我的程序中,我定义了一个接口并对其进行类型提示。这允许PHPStorm正确检测类

答案 1 :(得分:1)

如果您在课程find()中重新定义RepositoryA,则只需使用@return DomainA注释其实施。否则,请在find()的docblock中将@method声明为RepositoryA,并将DomainA作为其返回类型。

两种方法显示如下:

/**
 * @method DomainA find()          <-- use this when the method is inherited 
 *                                     but not redefined in this class
 */
class RepositoryA extends Repository
{
    /**
     * @return DomainA             <-- preferably use this
     */
    public function find()
    {

    }
}

类似的技巧可以用于子类中的继承属性存储类的对象,这些类扩展了基类中注释中使用的类:

/**
 * @property DomainA $member       <-- it was declared as @var Domain $member
 *                                     in the base class
 */

答案 2 :(得分:1)

PSR-5定义了 @method 标记。

语法

@method [return type] [name]([type] [parameter], [...]) [description]

实施例

/**
 * @method string getString()
 * @method void setInteger(int $integer)
 * @method setString(int $integer)
 */
class Child extends Parent
{
    <...>
}


abstract class EntitySerializer {
  /**
   * @return Entity
   */
  abstract public function getEntity();
}

/**
 * @method RealEntity getEntity()
 */
abstract class RealEntitySerializer extends EntitySerializer {}

/**
 * @method PseudoEntity getEntity()
 */
abstract class PseudoEntitySerializer extends EntitySerializer {}

Re:取自SO answer here