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

随声附和 提交于 2019-12-12 05:26:50

问题


In my PHP application I have a base class for all database objects, which is further extended by specific model classes. It goes on like this (simplified):

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

    (...)

}

The point is, I use the getById function on child classes to obtain the needed objects. However, since the return type of getById method is Model, PhpStorm can't figure out what methods the objects has and highlights the ones I use as an error. Consequently, no type-hinting available.

For instance, assuming that final class User extends Model and that class User has method sendNotification, this kind of code:

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

has sendNotification yellowed out as though it did not exist.

I know this isn't that much of an issue, but it's really irritating in terms of that I get distracted by constant redundant warnings and that I can't use type-hinting in such a usage case.


回答1:


Try with actual PHPDoc for your getById() where you specify dynamic type (e.g. @return static or @return $this).

That's the most common way of providing such "this class and its' children" typehint.


Another possible option is kind of the same .. but using PHP 7.1 functionality (so no PHPDoc blocks).

Try using self as return type instead of Model. I mean here:

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

use this instead:

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

But for this one you should use PhpStorm 2017.2 EAP build as 2017.1.x has issues with that (see https://stackoverflow.com/a/44806801/783119 as an example).




回答2:


There are three ways to achieve this, none of them has anything to do with PHPStorm.

First overwrite the method in every child with the proper return type:

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

Second add all possible children to the return tag of the abstract class.

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

Third add a type hint just in place:

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

These are not nice and hard to maintain. But there is no "setting" in PHPStorm for that.



来源:https://stackoverflow.com/questions/44912006/phpstorm-not-finding-methods-in-objects-created-by-late-static-binding-by-parent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!