从构建器方法调用的类型提示方法
Posted
技术标签:
【中文标题】从构建器方法调用的类型提示方法【英文标题】:Type hinting methods called from builder method 【发布时间】:2017-10-23 02:50:05 【问题描述】:考虑一个使用静态构建器返回模型实例的 Active Record 实现。这是要演示的 ModelBuilder 和 Model 类的非常简化版本,所有与问题无关的代码都已删除:
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
为了得到一个 Foo 项目,我们这样调用 FooModel 类:
$foo = FooModel::builder()->one();
在这种情况下,智能 IDE(在我的情况下为 phpStorm)不知道 $foo
是什么类型的对象。我可以在每次创建对象时对变量 /** @var $foo FooModel */
进行类型提示,但我更喜欢在 all()
和 one()
方法上进行适当的类型提示。
添加到all()
和one()
方法的正确类型提示是什么? 请注意,static
不起作用,我相信因为 ModelBuilder 不是初始调用的祖先类,它在builder()
方法中被显式调用。
这个特定项目使用的是 PHP 5.6,但也欢迎使用 PHP 7 特定的答案。
【问题讨论】:
你不能。添加该表扬是唯一可行的选择。当然,我也建议不要使用活动记录反模式,但这只是我对 OOP 和 SRP 的愚蠢想法。 @tereško:我很高兴听到你反对 ActiveRecord 模式的论点,因为我经常使用它。我想学习更好的方法。 使用更好的持久化模式称为“data mapper”,但也有“表数据网关”之类的东西(有些人习惯将其描述为“存储库”,尽管这并不是说)。避免 AR 的主要原因是性能。 【参考方案1】:如果您的模型具有像 BaseModel
这样的父类 - 您可以在文档块内的返回块中使用 BaseModel
all
和 one
方法,例如:
/**
* @return BaseModel Model instance.
*/
public function one()
return $this->_execute()[0];
但在这种情况下 - 它只是 BaseModel
它不是 FooModel
也不是 BooModel
...
您将只能访问 BaseModel 方法和属性,但不能访问特定于 FooModel...
为了拥有特定模型 - 您已经使用适当的文档块覆盖子模型中所需的方法,例如:
class FooModel extends BaseModel
/**
* @return FooModel Foo model instance.
*/
public function one()
return parent::one();
或者有类的文档块,像这样:
/**
* @method FooModel one Foo model instance.
*/
class FooModel extends BaseModel
或者像你已经提到的那样使用 doc-block /** @var $foo FooModel */
。
【讨论】:
谢谢。事实上,我正在寻找一种让FooModel
属性可用的方法,而不仅仅是Model
的属性,并且我想避免仅仅为了类型提示而重写每个扩展类中的方法。我想它要么是覆盖,要么我必须坚持使用文档块。
我已经更新了我的答案,添加了示例 @method FooModel one Foo model instance.
您可以为 FooModel
类设置此块,因此您不必覆盖 one
方法。
感谢您的更新,我不知道课堂上的@method
类型提示。好的!但是,它在这里不起作用,因为one()
是ModelBuilder
类的方法,而不是Model
。以上是关于从构建器方法调用的类型提示方法的主要内容,如果未能解决你的问题,请参考以下文章
在 iOS 中调用 Google Toolbox for Mac NSString 类别方法时无法识别的选择器