PHP:如何从静态方法获取类成员变量?

时间:2012-05-02 21:36:17

标签: php oop

我正在尝试创建一个具有静态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 个答案:

答案 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;

使用selfstatic关键字访问它,具体取决于您是否需要延迟静态绑定:

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)或类似的东西,通过这种方式,你可以隔离谁使用谁的责任。