从构建器方法调用的类型提示方法

时间:2017-05-23 08:43:14

标签: php oop phpstorm type-hinting

考虑一个Active Record实现,它使用静态构建器来返回模型的实例。这是一个非常简化版本的ModelBuilder和Model类来演示,所有代码都与删除的问题无关:

CreateObject("WScript.Shell").Run("cmd.exe /c  xcopy /y /s """ & Source & """ """ & Dest & """", WindowStyle:=7 , WaitOnReturn:=(your boolean) )

要获取Foo项,我们将调用FooModel类:

class ModelBuilder {
    public function __construct($class) {
        $this->class = $class
    }

    private function _execute() {
        $result = $pdo->query("SELECT * FROM {$this->class}");
        return $result->fetchAll(PDO::FETCH_CLASS, $this->class);
    }

    public function all() {
        return $this->_execute();
    }

    public function one() {
        return $this->_execute()[0];
    }
}

class Model {
    public static function builder() {
        return new ModelBuilder(get_called_class());
    }
}

class FooModel extends Model {

}

在这种情况下,智能IDE(在我的案例中是PhpStorm)不知道对象$foo = FooModel::builder()->one(); 是什么类型的。我可以在每次创建对象时键入提示变量$foo,但我希望在/** @var $foo FooModel */all()方法上使用正确的类型提示。

提示添加到one()all()方法的正确类型是什么?请注意one()不起作用,我相信因为ModelBuilder不是初始被调用类的祖先,它在static方法中被显式调用。

这个特殊项目使用的是PHP 5.6,但也欢迎PHP 7特定的答案。

1 个答案:

答案 0 :(得分:1)

如果您的模型有BaseModel之类的父类,则可以在doc-block中的BaseModelall方法的回复块中使用one,例如:

/**
* @return BaseModel Model instance.
*/
public function one() {
    return $this->_execute()[0];
}

但在这种情况下 - 它只是BaseModel它不是FooModel也不是BooModel ......
您只能访问BaseModel方法和属性,但不能访问FooModel特定的...

出于某种模式的目的 - 您在子模型中使用适当的doc-block覆盖了所需的方法,例如:

class FooModel extends BaseModel
{
    /**
    * @return FooModel Foo model instance.
    */
    public function one() {
        return parent::one();
    }
}

或者有课程的doc-block,像这样:

/**
 * @method FooModel one Foo model instance.
 */
class FooModel extends BaseModel
{
}

或者像你已经提到的那样使用doc-block /** @var $foo FooModel */