PhpStorm 未在由父抽象的后期静态绑定创建的对象中找到方法 class

PhpStorm not finding methods in objects created by late static binding by parent abstract class

在我的 PHP 应用程序中,我有一个用于所有数据库对象的基础 class,它由特定模型 class 进一步扩展。它继续像这样(简化):

abstract class Model extends Collection {

    (...)

    function __construct(string $primary_key, string $value) {
        $data = MysqlDB::instance() -> select(static::TABLE, implode(',', static::COLUMNS), "$primary_key=\"$value\"");
        if (count($data) != 1)
            throw new ModelException('Select condition uncertain');
        parent::__construct($data[0]);
    }

    public static function getById(string $id) : ?Model {
        try {
            return new static('id', $id);
        } catch (ModelException $e) {
            return NULL;
        }
    }

    (...)

}

关键是,我在子 classes 上使用 getById 函数来获取所需的对象。但是,由于 return 类型的 getById 方法是 Model,PhpStorm 无法弄清楚对象具有哪些方法,并突出显示我使用的方法作为错误。因此,没有可用的类型提示。

例如,假设 final class User extends Model 和 class User 有方法 sendNotification,这种代码:

User::getById($id) -> sendNotification($param1, $param2, ...)

已经sendNotification变黄了,就好像它不存在一样。

我知道这不是什么大问题,但它真的很烦人,因为我会被不断重复的警告分散注意力,而且我不能在这种情况下使用类型提示。

可通过三种方式实现,none 其中与 PHPStorm 有关。

首先用正确的 return 类型覆盖每个 child 中的方法:

/**
 * @return User
 */
public static function getById(string $id) : ?Model { return parent::getById($id); }

其次将所有可能的children添加到摘要class的return标签中。

/**
 * @return Model|User|...
 */
public static function getById(string $id) : ?Model { /* ... */ }

第三次添加类型提示:

/** @var User $user */
$user = User::getById($id);
$user->sendNotification($param1, $param2, ...);

这些不是很好,也很难维护。但是 PHPStorm 中没有 "setting"。

尝试为您的 getById() 使用实际的 PHP 文档,在其中指定动态类型(例如 @return static@return $this)。

这是提供此类 "this class and its' children" 类型提示的最常见方式。


另一个可能的选项有点相同..但使用 PHP 7.1 功能(因此没有 PHPDoc 块)。

尝试使用 self 作为 return 类型而不是 Model。我的意思是:

public static function getById(string $id) : ?Model {

改用这个:

public static function getById(string $id) : ?self {

但是对于这个你应该使用 PhpStorm 2017.2 EAP build 作为 2017。1.x 有问题(参见 作为例子)。