php - 无需更改数千行代码即可创建静态数组

标签 php arrays static

我们有一个包含名为 $saved 的公共(public)数组的类,该数组包含在方法之间共享所需的大量数据(下面的示例)...

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 的引用,所以我想尝试保持代码相同但使其静态。

这是我尝试使 $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->savedUser 初始化时为空,似乎不是同一个变量,最后的 print_r 而已显示 name => bob 的数组。

有什么想法吗?

最佳答案

首先,我不得不说,IMO,将实例的属性用作类的属性并不是那么好($saved 未声明为static 但它的值与所有实例共享)。

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

class Accumulator implements ArrayAccess {

    private $container = array();
    private static $instance = null;

    private function __construct() {
    }

    public function getInstance() {
        if( self::$instance === null ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function offsetSet($offset, $value) {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }

    public function offsetExists($offset) {
        return isset($this->container[$offset]);
    }

    public function offsetUnset($offset) {
        unset($this->container[$offset]);
    }

    public function offsetGet($offset) {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }

}


class Common {
    public $saved = null;


    public function __construct() {
        // initialize the "saved" object's property with the singleton
        // that variable can be used with the array syntax thanks to the ArrayAccess interface
        // so you won't have to modify your actual code
        // but also, since it's an object, this local "$this->saved" is a reference to the singleton object
        // so any change made to "$this->saved" is in reality made into the Accumulator::$instance variable
        $this->saved = Accumulator::getInstance();
    }

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

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

}


class Template extends Common {

    // you can redeclare the variable or not. Since the property is inherited, IMO you should not redeclare it, but it works in both cases
    // public $saved = null;

    public function __construct() {
        // maybe we can move this initialization in a method in the parent class and call that method here
        $this->saved = Accumulator::getInstance();
    }

}

关于php - 无需更改数千行代码即可创建静态数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10706040/

相关文章:

php - 将 php 脚本的返回结果(在执行查询以显示消息时)与我的字符串对象进行比较时出错

php - 将现有的 pdf 添加到 fpdf

php - mysql如何进行多表操作?

java - 静态变量什么时候初始化?

php - 如何捕获 Uncaught TypeError fatal error ?

arrays - numpy.load 以错误的顺序检索保存的数组

javascript - 将值添加到多维数组

php - 按索引累积二维数组

java - 这在Java中是线程安全的吗?

C++ 写入 myArray[0] 并设置 myInt = myFloat,为什么这样工作?