抽象类中的PHP静态变量

时间:2011-10-17 18:36:32

标签: php abstract-class static-members

我正在开发一个项目,我希望能够在抽象基类中声明一个静态成员变量。我有一个Model类,一个中间Post类,最后是一个特定于站点的Post类,如下所示:

abstract class Model {
    protected static $_table    = null;
    protected static $_database = null;

    ...
}

abstract class PostModel extends Model {
    public function __construct() {
        if ( !isset(self::$_table) ) {
            self::$_table = 'some_table';
        }

        parent::__construct();
    }

    ...
}

class SitePostModel extends PostModel {
    public function __construct() {
        if ( !isset(self::$_database) ) {
            self::$_database = 'some_database';
        }

        parent::__construct();
    }

    ...
}

我想从Model类中明白需要$ _table和$ _database成员。但是,从PostModel类的角度来看,$ _table实际上是静态的,从SitePostModel类的角度来看,$ _database实际上是静态的。

这是实现目标的合法途径吗?声明模型本身中的静态变量是否意味着它们应该只对抽象基类存在一次,或者对于实际的实例化类只存在一次?

2 个答案:

答案 0 :(得分:1)

  

这是实现目标的合法途径吗?

没有。它没有用,所以它没有通过合法性的基本测试。

  

声明Model本身中的静态变量是否意味着它们应该只对抽象基类存在一次,或者对于实际实例化的类只存在一次?

静态变量是全局的,它们只存在一次。在你的情况下每个类名。如果您有三个类名,那么您将拥有三个(全局)变量。 protected关键字仅控制三个静态变量的可见性/范围:

<?php

class A {
   protected static $v = 'red';
   public static function get() { return self::$v . ' - ' . static::$v;}
}

class B extends A {
   protected static $v = 'blue';
}

class C extends B {
   protected static $v = 'green';
}

echo C::get(); # red - green

答案 1 :(得分:0)

我最近遇到了同样的问题并找到了相同的解决方案 - 将设置放入静态变量并使用static关键字访问它们。它也适用于您可能希望在子类中覆盖的默认设置(例如每页的行数)。这似乎是最直观,最有效的方式。

我考虑的替代方案:

  • 使用静态抽象getter函数。它需要更多代码行和更多函数调用。
  • 将设置保存在非静态成员变量中,让子类构造函数担心它。我拒绝了这个选项,因为我的子类不需要构造函数。