PHP Serialize object tree

前端 未结 2 1837
野的像风
野的像风 2021-01-15 17:04

I have an object tree like the following, which I need to serialize and store on the filesystem. I need the full hierarchy with all class properties and later I will unseria

相关标签:
2条回答
  • 2021-01-15 17:48

    This is how I would recommend serializing objects:

    class Color implements \Serializable
    {
        private $Name;
        private $Type;
    
        public function __construct(string $Name, int $Type)
        {
            $this->Name = $Name;
            $this->Type = $Type;
        }
    
        public function serialize()
        {
            $Props['Name'] = $this->Name;
            $Props['Type'] = $this->Type;
            return serialize($Props);
        }
    
        public function unserialize($Data)
        {
            list($this->Name, $this->Type) = unserialize($Data);
        }
    }
    
    class Blue extends Color
    {
        private $Intensity;
    
        public function __construct()
        {
            parent::__construct('Blue', 10);
            $this->Intensity = 90;
        }
    
        public function serialize()
        {
            $Props['parent'] = parent::serialize();
            $Props['Intensity'] = $this->Intensity;
            return serialize($Props);
        }
    
        public function unserialize($Data)
        {
            $Obj = unserialize($Data);
            parent::unserialize($Obj['parent']);
            $this->Intensity = $Obj['Intensity'];
        }
    }
    

    Whichever object you pass in to the serialize() function is the object you will get back (as a string) to unserialize(). If you go your route, then you can implement the serialize()/unserialize() functions inside a trait and get_object_vars() will work properly for private variables.

    0 讨论(0)
  • 2021-01-15 17:49

    I have implemented serialize() and unserialize() in every affected class like this:

            public function serialize() {
    
                $res = array();
    
                $reflect = new \ReflectionClass(__CLASS__);
                $propList = $reflect->getProperties();
    
                foreach($propList as $prop) {
                        if ($prop->class != __CLASS__) {
                                continue; // visible properties of base clases
                        }
    
                        $name = $prop->name;
                        $res[$name . ":" . __CLASS__] = serialize($this->$name);
                }
    
                if (method_exists(get_parent_class(__CLASS__), "serialize")) {
                        $base = unserialize(parent::serialize());
                        $res = array_merge($res, $base);
                }
    
                return serialize($res);
        }
    
        public function unserialize($data) {
    
                $values = unserialize($data);
                foreach ($values as $key => $value) {
    
                        // key contains propertyName:className
                        $prop = explode(":", $key);
                        if ($prop[1] != __CLASS__) {
                                continue;
                        }
    
                        $this->$prop[0] = unserialize($value);
                }
    
                // call base class
                if (method_exists(get_parent_class(__CLASS__), "unserialize")) {
                        parent::unserialize($data);
                }
        }
    

    Maybe there is a solution to add this functionality to a base class to prevent code copies. It should work with simple properties, arrays and objects also for large object trees with multiple levels of parent classes.

    0 讨论(0)
提交回复
热议问题