避免 php serialize() 中的空字节

问题描述 投票:0回答:2

我正在使用 php serialize() 序列化 php 对象。但是,它会在受保护成员变量的结果中添加空字节。然后,该结果作为消息传递到 Amazon SQS 队列。问题是 SQS 不支持消息正文中的空字节。有什么办法可以摆脱空字节。我必须确保结果在另一端仍然不可序列化。

php serialization amazon-sqs
2个回答
3
投票

我在尝试序列化对象时遇到了同样的问题。

Michael - sqlbot评论中所述,

base64_encode
函数正确处理NUL字节。

在“序列化”方面你应该这样做:

base64_encode(serialize($object));

在“反序列化”方面:

unserialize(base64_decode($object));

如果你想了解

serialize
函数内部是如何工作的,你可以阅读 PHP 内部书籍:序列化

上面的序列化字符串中的都是NUL字节。正如您所看到的,私有和受保护的成员使用相当特殊的名称进行序列化:私有属性以 ClassName 为前缀,受保护属性以 * 为前缀。这些名称是名称修改的结果,我们将在后面的部分中介绍这一点。


0
投票

要直接回答问题,您可以像这样删除空字节:

$string = str_replace("\0", "", $string);

如果您存储序列化信息(不建议长期存储),那么将来使用较新的代码对其进行反序列化可能会导致问题,特别是如果您删除了空字符。您可以添加此方法来处理已删除或更新的属性:

/**
 * @copyright 2024 Frank Forte
 * @licence MIT
 */ 
public function __unserialize(array $data): void
{
    $deprecated_props = ['removed_property'];

    foreach ($data as $key => $value) {
        // serialize function identifies protected/private member
        // variables with the syntax null*null
        if (substr($key,0,3) == "\0*\0") { // or $key[0] == '*' if nulls removed from serialized string
            $key = substr($key, 3);
        }
        $prop = "\0" . static::class . "\0"; // without the "\0"s if nulls removed from serialized string
        $len = strlen($prop);
        if (substr($key,0,$len) == $prop) {
            $key = substr($key, $len);
        }

        // Avoid "Creation of dynamic property MyClass::$prop is deprecated" error.
        if (in_array($key, $deprecated_props)) {
            continue;
        }

        $this->$key = $value;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.