0

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

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;
        }
    }

    (...)

}

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

例如,假设那个final class User extends ModelUser有方法sendNotification,这种代码:

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

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

我知道这不是什么大问题,但是这真的很烦人,因为我被不断的冗余警告分心,而且在这种用例中我不能使用类型提示。

4

2 回答 2

2

getById()在您指定动态类型(例如@return static@return $this)的位置尝试使用实际的 PHPDoc 。

这是提供此类“此类及其子级”类型提示的最常见方式。


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

尝试使用self作为返回类型而不是Model. 我的意思是这里:

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

改用这个:

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

但是对于这个,您应该使用 PhpStorm 2017.2 EAP 构建,因为 2017.1.x 存在问题(参见https://stackoverflow.com/a/44806801/783119作为示例)。

于 2017-07-04T19:56:42.793 回答
1

有三种方法可以实现这一点,它们都与 PHPStorm 无关。

首先用正确的返回类型覆盖每个孩子的方法:

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

其次将所有可能的孩子添加到抽象类的返回标签中。

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

第三,就地添加类型提示:

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

这些不好且难以维护。但是 PHPStorm 中没有“设置”。

于 2017-07-04T18:19:30.447 回答