我正在尝试创建一个具有静态Model
方法的抽象fetchAll
类。子类需要指定将在fetchAll
方法中使用的名称/位置。但是,我无法弄清楚如何以可从静态方法和非静态方法访问的方式指定protected $_name
方法。这就是我到目前为止所做的:
abstract class Model
{
protected $_name;
public static function fetchAll()
{
$request = new ApiRequest();
return $request->get($this->_name);
}
public function save()
{
$request = new ApiRequest();
return $request->put($this->_name, $this->_data);
}
}
class Email extends Model
{
protected $_name = 'zEmailz';
}
答案 0 :(得分:3)
您是否考虑将名称作为参数传递给fetchAll()
方法?
class Email extends Model
{
protected $_name = 'zEmailz';
public function getResults()
{
$rows = parent::fetchAll($this->$_name);
}
}
我不建议将Model::$_name
设置为静态,因为任何可能的迭代都可能会覆盖该值,并且难以确保当前值与您想要的值匹配。这是混合静态和实例化成员的众多陷阱之一。
- 更新 -
你可以将对象传递给fetchAll
调用,有点像(比如说,我从来没有将DI与静态调用混合在一起),这是一种依赖注入解决方案:
// Calling code
$email = new Email();
// Do stuff with $email
$results = Model::fetchAll($email);
然后模型类看起来像:
abstract class Model
{
public static function fetchAll($object)
{
$request = new ApiRequest();
return $request->get($object->_name);
}
}
- 更新#2 -
根据您的评论,您正在寻找一种方法来从数据库中检索行并保存主要对象,以便您可以通过OO API调用来引用当前值。如果我是你,你会看看Doctrine,而不是重新发明轮子。在Doctrine中,他们拥有所谓的“表”类,它们与模型类直接相关。例如,您将拥有一个EmailTable.php
文件,在此类中,您将添加自定义方法以返回所需的数据集。
如果您仍然希望坚持自己的方式,那么您可能希望将fetchAll
方法移动到每个子类中,否则如果您将它保留在父类中,您将最终带有令人讨厌的开关/外壳块,适合所有想要保湿的物体。
示例(仅限说明):
class Email extends Model
{
protected $_name = 'zEmailz';
public static function fetchAll()
{
// However you pull rows from DB
while ($row = get_current_row) {
$email = new Email();
$email->setAddress($row['address']);
...
$emails[] = $email;
}
return $emails;
}
}
答案 1 :(得分:2)
只需将变量声明为static:
protected static $_name;
使用self
或static
关键字访问它,具体取决于您是否需要延迟静态绑定:
return $request->get(static::$_name);
答案 2 :(得分:1)
如果要从静态方法访问静态_name变量,请使用self :: $ _ name
但是将静态方法用于基类并不是一个好主意 意识到,这个方法只会处理静态数据(所有后代都很常见)。 因此,如果要访问后代的所有名称,则必须添加模型名称的静态数组,还可以存储params,classname或链接到后代对象。然后,您可以访问所有后代,或者只按名称或类名选择一个,或者从存储的参数中选择其他一些ID。
答案 3 :(得分:1)
我可能错了,但如果模型是抽象类,他们没有责任知道谁在使用它们。他们只指定从他那里继承的所有类都有一个fetchall方法,这个方法可以有或没有实现,但是他必须存在。
如果您有一个继承自Abstract Model Class的实体,则应使用签名Entity :: fetchall()调用。
Entity :: fetchall()可以在内部调用parent :: fetchall($ name)或类似的东西,通过这种方式,你可以隔离谁使用谁的责任。