php serialize trickery
30 November 2006 // php. stuff.
A couple of code snippets that show how to do some intriguing stuff in oop php using serialization
changing the class of an instance
Convert object to a new class is fairly simple, because serializer stores class name along with object's data. The new mutated object inherits the properties from source object, but not methods.
function to_class($obj, $klass) {
return unserialize(preg_replace(
'/^O:\d+:\"(\w+)/',
'O:' . strlen($klass) . ':"' . $klass,
serialize($obj)));
}
# example
class A {
public $a_var = "var in A\n";
function a_method() {
echo "method in A\n";
}
}
class B {
public $b_var = "var in B\n";
}
$old = new B;
$new = to_class($old, 'A');
$new->a_method();
echo $new->a_var;
echo $new->b_var;
accessing private members
More convoluted (and far dirtier) serialize trick for accessing private members from outside of the class.
function get_private($obj, $member) {
$c = get_class($obj);
$s = array("O:".strlen($c).":\"$c\"", "\000$c\000$member");
$r = array("O:8:\"stdClass\"", "\001$c\001$member");
$q = unserialize(str_replace($s, $r, serialize($obj)));
return $q->{$r[1]};
}
function set_private(&$obj, $member, $value) {
$c = get_class($obj);
$s = array("O:".strlen($c).":\"$c\"", "\000$c\000$member");
$r = array("O:8:\"stdClass\"", "\001$c\001$member");
$q = unserialize(str_replace($s, $r, serialize($obj)));
$q->{$r[1]} = $value;
$obj = unserialize(str_replace($r, $s, serialize($q)));
}
# example:
class A {
private $x = 'foo';
function echo_priv() {
echo "private x= ", $this->x, "\n";
}
}
$a = new A();
echo get_private($a, 'x'), "\n";
$a->echo_priv();
set_private($a, 'x', 'NEW');
$a->echo_priv();
Important notice: these functions are not for use in production environments. ;)
If you think this comment is spam or otherwise completely irrelevant here,
feel free to hide it.
The comment disappears immediately, though it is not deleted,
so I have an option to "unhide" it later.
comment on this