假设我有一个这样的课程
class ClassA {
public $publicMember;
private $privateMember;
protected $protected;
}
我将对象ClassA编码为:
$objectA = new ClassA();
$stringA = base64_encode(serialize($objectA));
我想替换所有受保护的成员,但我不知道如何。我试过这样的事:
$newString = str_replace('�*�', '', base64_decode($stringA));
对不起,这个问题很简单,但我真的不知道如何处理这个问题。谢谢!
答案 0 :(得分:1)
属性名称前面有长度。
string(92) "O:6:"ClassA":3:{s:12:"publicMember";N;s:21:"\000ClassA\000privateMember";N;s:12:"\000*\000protected";N;}"
| property name length ^ ^ ^
| we will try to capture this part ^ ^
如果要将受保护的内容“转换”为公共内容,您可以减少此长度。例如。
class ClassA
{
public $publicMember;
private $privateMember;
protected $protected;
}
$objectA = new ClassA();
$stringA = serialize($objectA);
$converted = preg_replace_callback('@:(\d+):"\x00\*\x00@', function($match)
// ^ catch the number
// ^ ^ null symbols
{
$property_name_length = $match[1];
return ':' . ($property_name_length - 3) . ':"'; // reduce catched number and do not return \x00*\x00
}, $stringA);
var_dump(unserialize($converted));
可生产
class ClassA#2 (4) {
public $publicMember =>
NULL
private $privateMember =>
NULL
protected $protected =>
NULL
public $protected =>
NULL
}
P.S。但是,当您开始将序列化的数据存储为成员值时,此代码将失败。
答案 1 :(得分:0)
让我们尝试另一种方式:
-
class ClassA
{
public $publicMember;
private $privateMember;
protected $protected;
}
$objectA = new ClassA();
$stringA = serialize($objectA);
// 1. convert serialzed class to stdClass
$stringA = preg_replace('/' . strlen('ClassA') . '/', strlen('stdClass'), $stringA, 1);
$stringA = preg_replace('/ClassA/', 'stdClass', $stringA, 1);
// 2. unserialize
$object = unserialize($stringA);
// 3. add public protected properties
while (list($key, $value) = each($object)) // hack with each
{
if (strpos($key, "\x00*\x00") === 0)
{
$key = str_replace("\x00*\x00", '', $key);
$object->$key = $value;
}
}
// 4. serialize
$stringB = serialize($object);
// 5. convert serialized stdClass to original
$stringB = preg_replace('/' . strlen('stdClass') . '/', strlen('ClassA'), $stringB, 1);
$stringB = preg_replace('/stdClass/', 'ClassA', $stringB, 1);
var_dump(unserialize($stringB));
可生产
class ClassA#3 (4) {
public $publicMember =>
NULL
private $privateMember =>
NULL
protected $protected =>
NULL
public $protected =>
NULL
}
P.S。它比第一个更安全,但......:)