PHP:将类的引用设置为常量......?

时间:2009-12-31 02:20:47

标签: php

我有一组已定义的常量,对于某些我正在序列化类的新实例并设置为常量(可能不是最好的想法,我知道......),问题是当信息发生变化时类的实例,它不会更新在常量中声明的引用内存...我知道一个常量不能被改变,但它不是真的只是指向一块内存而且当那个内存信息是改变了,那么常数的返回值是什么?在我把任何人与我说的话混淆之前,我只会告诉你我做了什么:

<?php
    class Collection {
        var $items = array();

        public function __construct() { }

        public function add($val) {
            array_push($this->items, $val);
        }

        public function dump() {
            var_dump($this->items);
        }
    }

    $collection = new Collection();
    define('COLLECTION', serialize(&$collection));
    unserialize(COLLECTION)->add('test item 1');
    unserialize(COLLECTION)->add('test item 2');
    unserialize(COLLECTION)->dump();
    /* It will end up dumping this:
       array(0) { }
     */
?>

现在我之所以这样做是因为我将在许多(30多个)不同的php文件中使用这些常量,在许多函数中,我知道这可以通过简单地使用变量并使用{来完成{1}}在每个函数中,但我试图避免它,因为大多数服务器都关闭了全局变量。请告诉我是否有更好的方法来接近它。

- 谢谢!
Nadeem

5 个答案:

答案 0 :(得分:4)

更好的选择是实现Singleton模式或类似的东西,以避免序列化:

class Collection {
    var $items = array();

    public function __construct() { }

    public function add($val) {
        array_push($this->items, $val);
    }

    public function dump() {
        var_dump($this->items);
    }

    public function push($v) {
        $this->items[]= $v;
    }

    static protected $_instance = null;
    static public function get() {
       if (empty(self::$_instance)) self::$_instance= new Collection();
       return self::$_instance;
    }

}

Collection::get()->push('test item 1');
Collection::get()->push('test item 2');
Collection::get()->dump();

答案 1 :(得分:2)

为什么不定义一个函数?

function push_item($item) {
  global $collection;
  $collection->push($item);
}

比定义一个序列化类的常量(这几乎是WTF领域,对不起)要清晰得多。

答案 2 :(得分:1)

你的常量是存储一个字符串。当你取消序列化时,无论你对从它创建的类做什么,常量的值都不会改变(名字中的线索真的......)。在对您的问题的评论中采用Brad的建议并使用注册表。

答案 3 :(得分:1)

  

...因为大多数服务器都关闭了全局变量。

这个问题有几个混淆点,这就是其中之一。大多数服务器都关闭了register_globals选项。这并不妨碍您在应用程序中使用全局变量。该选项所做的就是从脚本开头将$_GET$_POST(以及更多)的值作为全局变量导入。

答案 4 :(得分:0)

****** ****解决

通过创建包含收集定义的静态数组的简单混合列表来解决问题。感谢所有的回复,你的建议帮助我把它们放在一起:

class MixedList {
    protected static $list = array();

    public static function set($key, $val) {
        self::$list[$key] = &$val;
        if (!defined($key)) eval("define('{$key}', '{$key}');");
    }

    public static function &get($key) {
        return self::$list[$key];
    }
}

// Usage:
MixedList::set('COLLECTION', new Collection());
MixedList::get(COLLECTION)->add('test item 1');
MixedList::get(COLLECTION)->add('test item 2');
MixedList::get(COLLECTION)->dump();
// You could also do wrap the arguments as a string, would do the same trick

- 谢谢!
Nadeem