我在Marco Pivetta的文章中读到,private
和protected
类属性可以通过(array)
的简单投射阅读,并在属性之前附加"keys"
:
"\0*\0"
- 受保护;
"\0CLASSNAME\0"
- 私人。
class Foo {
protected $a = 'protected_prop';
private $b = 'private_prop';
function out(){
var_dump($this->a);
var_dump($this->b);
}
}
$F = new F();
$data = (array)$F;
var_dump($data["\0*\0a"]);
var_dump($data["\0Foo\0b"]);
// output
string(14) "protected_prop"
string(12) "private_prop"
然后我决定尝试覆盖私有和受保护的属性。这个“钥匙”(\ 0Foo \ 0b)让我想起了关于血清化的信息。
$F = serialize($F);
$F = str_replace('protected_prop','new_protected_prop',$F);
$F = str_replace('private_prop','new_private_prop',$F);
$F = preg_replace_callback ( '!s:(\d+):"(.*?)";!', function($match) {
return ($match[1] == strlen($match[2])) ? $match[0] : 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
},$F ); // fix unserialize(): Error at offset after str_replacing. Found on SO ^)
$F = unserialize($F);
if ($F instanceof Foo){
$F->out();
}
// output
string(18) "new_protected_prop"
string(16) "new_private_prop"
object(Foo)#1 (2) {
["a":protected]=> string(18) "new_protected_prop" // changed
["b":"Foo":private]=> string(16) "new_private_prop" // changed
}
问题:为什么我们可以通过这种方法在外部更改所有私有和受保护的属性?或者它在序列化中的语言(PHP)冲突?谢谢。