note 103744 added to function.unserialize
| From: | i dot chiriac at yahoo dot com | Date: | Sun, 01 May 2011 17:14:30 +0000 |
| Subject: | note 103744 added to function.unserialize | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-179321@lists.php.net to get a copy of this message | ||
Hi,
I'm working with serialized objects stored on files and I've found a problem and his fix
when you modify the serialized object subclassing. When you serialize a class with a private
property, the subclassing of this private property will simply not work because each private
property is attached to it's class level.
For example, you start to implement and serialize this class :
<?php
class bar {
private $var = 'bar value';
public function getValue() {
return $this->var;
}
}
?>
You store an instance of the bar class into a file as a serialized string.
After some code refactoring you prefer to store the value in a subclass like this :
<?php
class foo {
private $var = 'bar value';
public function getValue() {
return $this->var;
}
}
class bar extends foo {
}
?>
When you retrieve the stored bar instance from the srialized file, you have lose the $var value.
The only solution is to store private vars as protected properties and not private ones.
If you want to migrate/convert serialized private values as protected values you can use the
following code :
<?php
function setProtected($serialized, $vars) {
if ($serialized[0] != 'O') {
throw new Exception('The serialized string is not representing a class');
}
$size = '';
for($i = 2; $i < strlen($serialized); $i++) {
if ($serialized[$i] == ':') break;
$size .= $serialized[$i];
}
$class = substr($serialized, $i + 2, $size);
$find = array();
$replace = array();
foreach($vars as $name) {
$from = chr(0).$class.chr(0).$name;
$to = chr(0).'*'.chr(0).$name;
$find[] = 's:'.strlen($from).':"'.$from.'";';
$replace[] = 's:'.strlen($to).':"'.$to.'";';
}
return str_replace($find, $replace, $serialized);
}
// example of use
$obj = unserialize(
setProtected(
file_get_contents('object.ser'),
array('property1', 'propetyN')
)
);
?>
Hope this will helps someone,
aKhEnAtHoN
----
Server IP: 69.147.83.197
Probable Submitter: 83.115.187.113
----
Manual Page -- http://www.php.net/manual/en/function.unserialize.php
Edit -- https://master.php.net/note/edit/103744
Del: integrated -- https://master.php.net/note/delete/103744/integrated
Del: useless -- https://master.php.net/note/delete/103744/useless
Del: bad code -- https://master.php.net/note/delete/103744/bad+code
Del: spam -- https://master.php.net/note/delete/103744/spam
Del: non-english -- https://master.php.net/note/delete/103744/non-english
Del: in docs -- https://master.php.net/note/delete/103744/in+docs
Del: other reasons-- https://master.php.net/note/delete/103744
Reject -- https://master.php.net/note/reject/103744
Search -- https://master.php.net/manage/user-notes.php