简体   繁体   English

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

[英]PHP: Set reference to a class as a constant…?

I have a set of defined constants, and for some I'm serializing new instances of a class and setting as a constant (probably not the best idea, I know...), the problem is that when information changes in the instance of the class, it doesn't update the referenced memory that was declared in the constant... I know a constant cannot be altered, but isn't it really just pointing to a block of memory and when that memory information is changed, so should the returning value of the constant? 我有一组已定义的常数,对于某些人,我正在序列化一个类的新实例并将其设置为常数(我知道这可能不是最好的主意……),问题是当信息在实例中发生更改时该类,它不会更新在常量中声明的引用内存...我知道常量不能更改,但它不是仅指向内存块以及何时更改该内存信息,所以应该返回常数吗? Well before I confuse anyone with what I said, I'll just show you what I have done: 在将任何人与我所说的相混淆之前,我只告诉你我做了什么:

<?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) { }
     */
?>

Now the reason why I'm doing this is because I'll be using these constants in many(30+) different php files, inside many functions, I know this can be accomplished by simple just using the variable and using global $variable; 现在我这样做的原因是因为我将在许多函数中使用许多(30+)个不同的php文件中的这些常量,我知道这可以通过简单地使用变量和使用global $variable; in every function, but I'm trying to avoid it since most servers have globals turned off. 在每个函数中,但由于大多数服务器都关闭了全局设置,因此我试图避免这种情况。 Please tell me if there is a better way to approach it aswell. 请告诉我是否还有更好的方法来解决它。

- Thanks! - 谢谢!
Nadeem 纳德姆

A better option would be to implement the Singleton pattern or something like this, to avoid serialization: 更好的选择是实现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();

Why not just define a function? 为什么不仅仅定义一个函数呢?

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

It's a lot cleaner than defining a constant of a serialized class (that's almost WTF territory, sorry). 这比定义序列化类的常量要干净得多(抱歉,这几乎是WTF领域)。

Your constant is storing a string. 您的常数存储一个字符串。 When you unserialise it, the value of the constant doesn't change no matter what you do to the class you created from it (the clue's in the name really...). 当您反序列化它时,常量的值不会改变,无论您对从其创建的类执行什么操作(线索的名称确实是……)。 Take Brad's advice in the comment on your question and use a registry. 在对您的问题的评论中采纳Brad的建议,并使用注册表。

... since most servers have globals turned off. ...由于大多数服务器都关闭了全局设置。

There are several points of confusion in this question, and this is one of them. 这个问题有几个混淆点,这就是其中之一。 Most servers have the option register_globals turned off. 大多数服务器都关闭了register_globals选项。 That doesn't prevent you from using global variables in your application. 这不会阻止您在应用程序中使用全局变量。 All that the option does is that it imports values from $_GET and $_POST (and a few more) as global variables from the beginning of your script. 该选项所做的全部就是从脚本的开头将$_GET$_POST (以及更多)中的值作为全局变量导入。

******SOLVED**** ******解决了****

Solved the problem by creating a simple mixed list containing a static array of collected definitions. 通过创建一个简单的混合列表来解决此问题,该列表包含一个静态的已收集定义数组。 Thanks to all the replies, your suggestions helped me put this together: 感谢所有答复,您的建议帮助我将其归纳为:

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

- Thanks! - 谢谢!
Nadeem 纳德姆

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM