1

我正在尝试创建一个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';
}
4

4 回答 4

3

您是否考虑将名称作为参数传递给fetchAll()方法?

class Email extends Model
{
    protected $_name = 'zEmailz';

    public function getResults()
    {  
        $rows = parent::fetchAll($this->$_name);
    }    
}

我不建议将其设置Model::$_name为静态,因为任何可能的迭代都可能覆盖该值并难以确保当前值与您想要的匹配。这是混合静态成员和实例化成员的众多陷阱之一。

- 更新 -

您可以将对象传递给fetchAll调用,有点像(比如我从未将 DI 与静态调用混合在一起的 b/c)依赖注入解决方案:

// 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方法移动到每个子类中,否则如果您将其保留在父类中,您最终会得到一个讨厌的 switch/case 块所有你想要水合的物体。

示例(仅用于演示):

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;
    }
}
于 2012-05-02T21:43:19.823 回答
2

只需将变量声明为静态:

protected static $_name;

并使用selforstatic关键字访问它,具体取决于您是否需要后期静态绑定:

return $request->get(static::$_name);
于 2012-05-02T21:40:49.760 回答
1

如果您想从静态方法访问您的静态 _name 变量,请使用 self::$_name

但是在基类 Realize 中使用静态方法并不是一个好主意,该方法将仅处理静态数据(所有后代通用)。因此,如果要访问后代的所有名称,则必须添加模型名称的静态数组,也可以存储参数、类名或链接到后代对象。然后您可以访问所有后代,或者仅按名称或类名选择一个,或者从存储的参数中选择其他一些 id。

于 2012-05-02T21:52:59.070 回答
1

我可能是错的,但如果模型是一个抽象类,他们没有责任知道谁在使用它们。他们只规定所有继承自他的类,都会有一个fetchall方法,这个方法可以有实现也可以没有,但他必须存在。

如果你有一个继承自抽象模型类的实体,应该使用签名 Entity::fetchall() 来调用。

Entity::fetchall() 可以在内部调用 parent::fetchall($name) 或类似的方法,通过这种方式,您可以隔离谁使用谁的责任。

于 2012-05-02T22:59:08.607 回答