创建静态数组而不更改数千行代码

时间:2012-05-22 16:20:36

标签: php arrays static

我们有一个类,它包含一个名为$saved的公共数组,其中包含在方法之间共享所需的大量数据(例如下面的代码)......

class Common {
    public $saved = array();

    public function setUser($data) {
        $this->saved['user_data'] = $data;
    }

    public function getUserID() {
        return $this->saved['user_data']['id'];
    }
}

实际上有数千行代码可以这样工作。

问题是扩展Common的新实例是在某些方法中进行的,所以当他们访问$saved时,它不会保存相同的数据。

解决方案是使$saved成为一个静态变量,但是我无法更改$this->saved的所有引用,因此我想尝试保持代码相同但使其静态化。 / p>

我试图让$this->saved调用静态...

class PropertyTest {
    private $data = array();

    public function __set($name, $value) {
        $this->data[$name] = $value;
    }

    public function __get($name) {
        if (array_key_exists($name, $this->data)) {
            return $this->data[$name];
        }

        return null;
    }

    public function __isset($name) {
        return isset($this->data[$name]);
    }

    public function __unset($name) {
        unset($this->data[$name]);
    }
}

class Common {
    public $saved;
    private static $_instance;

    public function __construct() {
        $this->saved = self::getInstance();
    }

    public static function getInstance() {
        if (self::$_instance === null) {
            self::$_instance = new PropertyTest();
            self::$_instance->foo = array();
        }
        return self::$_instance->foo;
    }
}

设置变量时,这似乎不起作用,它似乎不会保持静态(下面的测试用例)......

class Template extends Common {

    public function __construct() {
        parent::__construct();
        $this->saved['user_data'] = array('name' => 'bob');
        $user = new User();
    }
}

class User extends Common {

    public function __construct() {
        parent::__construct();
        $this->saved['user_data']['name'] .= " rocks!";
        $this->saved['user_data']['id'] = array(400, 10, 20);
    }
}

$tpl = new Template();
print_r($tpl->saved['user_data']);
$this->saved初始化时

User为空且似乎不是同一个变量,最终print_r只显示名称=>的数组鲍勃。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

首先,我必须说,IMO,使用实例的属性作为类的属性$saved未声明为{{1}但它的值与所有实例共享。)

这是一个工作版本http://codepad.org/8hj1MOCT,这是注释代码。基本上,诀窍在于同时使用ArrayAccess interfacesingleton pattern

static

答案 1 :(得分:0)

我认为这个实现存在许多问题,很可能会再次出现。但是,在当前的实现中,每次都要构造一个新实例(尽管通过静态调用)。

而是使用getInstance()作为您的单例钩子,并使__construct为私有,因为您只能使用Common类的上下文访问它。​​

像这样:

class Common {
    public $saved;

    private static $_instance;

    private function __construct() {
    }

    public static function getInstance() {
        if (self::$_instance === null) {
            self::$_instance = new self();
            ... any other modifications you want to make ....
        }
        return self::$_instance;
    }
}

并且不要运行parent :: _ construct(),而是始终使用getInstance()方法。

你可能也想放弃扩展这个单例类的想法。这实际上是一个糟糕的反模式,从长远来看可能会花费你很多问题。而只是维护一个其他类可以读/写的Common类。作为单身人士,您无需担心注射。

答案 2 :(得分:0)

我似乎已经解决了这个问题,方法是让$this->saved引用一个静态变量来运行......

class Common {
    private static $savedData = array();
    public $saved;

    public function __construct() {
        $this->saved =& self::$savedData;
    }
}