我们有一个类,它包含一个名为$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
只显示名称=>的数组鲍勃。
有什么想法吗?
答案 0 :(得分:1)
首先,我必须说,IMO,使用实例的属性作为类的属性好($saved
未声明为{{1}但它的值与所有实例共享。)
这是一个工作版本http://codepad.org/8hj1MOCT,这是注释代码。基本上,诀窍在于同时使用ArrayAccess interface和singleton 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;
}
}