I'm running into a weird issue where if I try to serialize an array of objects of the same class, where that class has implemented the Serializable interface and in the serializable interface returns the serialized instance of another class, the array items after the first couple are considered recursive.
Here is a test case:
<?php
class HelloWorld implements Serializable {
public $test;
public function __construct($str)
{
$this->test = $str;
}
public function serialize()
{
$simple = null;
$simple = new Simple();
$simple->test = $this->test;
return serialize($simple);
}
public function unserialize($str)
{
$simple = unserialize($str);
$this->test = $simple->test;
}
}
class Simple
{
public $test;
}
$list = array(
new HelloWorld('str1'),
new HelloWorld('str2'),
new HelloWorld('str3'),
new HelloWorld('str4'),
new HelloWorld('str5'),
new HelloWorld('str6'),
new HelloWorld('str7'),
new HelloWorld('str8'),
new HelloWorld('str9'),
);
$str = serialize($list);
echo $str . "
";
// var_dump(unserialize($str));
Uncomment the last line and enjoy a php segmentation fault.
Does anyone know why this is or how to fix it? This doesn't seem to be an issue if what is being serialized in HelloWorld::serialize()
is an array or a primitive value.
Update:
Here is the output from the above code:
a:9:{i:0;C:10:"HelloWorld":39:{O:6:"Simple":1:{s:4:"test";s:4:"str1";}}i:1;C:10:"HelloWorld":4:{r:3;}i:2;C:10:"HelloWorld":4:{r:3;}i:3;C:10:"HelloWorld":4:{r:3;}i:4;C:10:"HelloWorld":4:{r:3;}i:5;C:10:"HelloWorld":4:{r:3;}i:6;C:10:"HelloWorld":4:{r:3;}i:7;C:10:"HelloWorld":4:{r:3;}i:8;C:10:"HelloWorld":4:{r:3;}}
The issue is the r:4;
stuff on the second and following records.
DAMN! Sorry, I read your question wrong. Thought you wanted to print all of them.
You need simple to be serializable. Otherwise it won't work, in order to serialize you need could use something like this:
class HelloWorld implements Serializable
{
public $test;
public function __construct($str)
{
$this->test = $str;
}
public function serialize()
{
return serialize($this->test);
}
public function unserialize($str)
{
$simple = unserialize($str);
$this->test = $simple;
}
}
The simple class is not needed. Remember that $this->data will always have to be serializable.