|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2019-12-25 09:52 UTC] syberon at gmail dot com
Description:
------------
Since version 7.4 of PHP the unserialize function can't process object references from serialized session strings.
For example, i have a few object stored in session with 3 namespaces (i exploded it to readability:
__ZF|a:2:{s:20:"_REQUEST_ACCESS_TIME";d:1577256665.394478;s:6:"_VALID";a:1:{s:25:"Zend\Session\Validator\Id";s:26:"uk2ngahnpc35k4rfsqd97kf9e6";}}
FlashMessenger|C:23:"Zend\Stdlib\ArrayObject":205:{a:4:{s:7:"storage";a:0:{}s:4:"flag";i:2;s:13:"iteratorClass";s:13:"ArrayIterator";s:19:"protectedProperties";a:4:{i:0;s:7:"storage";i:1;s:4:"flag";i:2;s:13:"iteratorClass";i:3;s:19:"protectedProperties";}}}
MtCms\User\Authentication\Adapter\DatabaseAdapter|C:23:"Zend\Stdlib\ArrayObject":644:{a:4:{s:7:"storage";a:1:{s:7:"storage";a:2:{s:12:"is_satisfied";b:1;s:8:"identity";O:8:"stdClass":13:{s:2:"id";s:1:"1";s:8:"username";s:5:"admin";s:5:"email";s:17:"syberon@gmail.com";s:12:"display_name";s:6:"Andrey";s:7:"picture";s:0:"";s:8:"delivery";s:1:"1";s:4:"city";s:22:"Новосибирск";s:9:"city_code";s:3:"270";s:8:"zip_code";s:6:"630000";s:7:"address";s:16:"ываывавы";s:5:"phone";s:4:"4234";s:5:"state";s:1:"1";s:10:"persistent";s:1:"1";}}}s:4:"flag";i:2;s:13:"iteratorClass";s:13:"ArrayIterator";s:19:"protectedProperties";a:4:{i:0;s:7:"storage";i:1;s:4:"flag";i:2;s:13:"iteratorClass";i:3;s:19:"protectedProperties";}}}
Zend_Auth|C:23:"Zend\Stdlib\ArrayObject":224:{a:4:{s:7:"storage";a:1:{s:7:"storage";r:20;}s:4:"flag";i:2;s:13:"iteratorClass";s:13:"ArrayIterator";s:19:"protectedProperties";a:4:{i:0;s:7:"storage";i:1;s:4:"flag";i:2;s:13:"iteratorClass";i:3;s:19:"protectedProperties";}}}
Second namespace 'MtCms\User\Authentication\Adapter\DatabaseAdapter' has object of class 'Zend\Stdlib\ArrayObject' that has a property with name 'storage' that contains anothe object.
Third namespace 'Zend_Auth' has the object of class 'Zend\Stdlib\ArrayObject' too. And this object has the same property 'storage' but it has value r:20 (reference to object of second namespace)
PHP 7.3 parses this serialized session data without any problems and at result we have a objects from 2nd and 3rd namespaces with property 'storage' what have identically object contain in.
But then i upgraded to PHP 7.4 the session_start() function give the error when trying to parse this session data. It can not recognize 'r:20' reference in object of 3rd namespace.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Tue Nov 11 08:00:02 2025 UTC |
I found that this problem is related to PHP 7.4 session unserializing. I made some tests and found that if some class (Zend\Stdlib\ArrayObject in my case) implements Serializable interface and has some property (object of stdClass for example) it failed to decode if stored in session. I made a minimal reproducible example: <?php class SerializableClass implements Serializable { public $sharedProp; public function __construct($prop) { $this->sharedProp = $prop; } public function __set($key, $value) { $this->$key = $value; } public function serialize() { return serialize(get_object_vars($this)); } public function unserialize($data) { $ar = unserialize($data); foreach ($ar as $k => $v) { $this->__set($k, $v); } } } // Shared object that acts as property of two another objects stored in session $testPropertyObj = new stdClass(); $testPropertyObj->name = 'test'; // Two instances of \SerializableClass that shares property $sessionObject = [ 'obj1' => new SerializableClass($testPropertyObj), 'obj2' => new SerializableClass($testPropertyObj), ]; session_start(); $_SESSION = $sessionObject; On first run it creates array with two instances of object with one shared property and store it in session. On second run it tries to start session and fail to parse the second object stored in session because the it loses reference to property 'name'. This script runs without any problems on PHP 7.3, and rises the parse errors on PHP 7.4.