【发布时间】:2015-11-11 19:52:47
【问题描述】:
我的项目与返回带有 PHP 序列化对象的字符串的 API 通信。通常,响应是一个序列化的数组,并且反序列化没有问题。但是,我们刚刚遇到了一个端点,它返回了一个我们以前没有遇到过的对象,我不确定如何创建一个可用于反序列化对象的类。
这是从 API 返回的内容(仅显示令人困惑的部分):
s:8:" * _data";a:1:{
i:4057353;C:25:"Transfer_Sales_Order_Item":201:{
a:5:{
s:8:"quantity";i:1;
s:19:"id_sales_order_item";s:7:"4057353";
s:4:"name";s:44:"Empacadora Selladora FoodSaver al Alto Vacio";
s:10:"paid_price";d:796.13999999999999;
s:3:"sku";s:15:"LI200HL37WWCLMX";
}
}
}
完整的序列化字符串:
O:16:"Service_Response":8:{s:11:" * _success";b:1;s:17:" * _errorMessages";a:0:{}s:19:" * _successMessages";a:0:{}s:22:" * _validationMessages";a:0:{}s:18:" * _noticeMessages";a:0:{}s:14:" * redirectUrl";N;s:23:" Service_Abstract _type";N;s:14:" * _resultData";a:1:{s:24:"NotAvailablesForTracking";O:40:"Transfer_Sales_Order_ItemCollection_test":6:{s:19:" * _objectClassName";s:25:"Transfer_Sales_Order_Item";s:15:" * _idAttribute";s:19:"id_sales_order_item";s:47:" Vendor_Transfer_AbstractCollection _indexDirty";b:0;s:8:" * _data";a:1:{i:4057353;C:25:"Transfer_Sales_Order_Item":201:{a:5:{s:8:"quantity";i:1;s:19:"id_sales_order_item";s:7:"4057353";s:4:"name";s:44:"Empacadora Selladora FoodSaver al Alto Vacio";s:10:"paid_price";d:796.13999999999999;s:3:"sku";s:15:"LI200HL37WWCLMX";}}}s:17:" * _setDataStrict";b:1;s:9:" * locale";N;}}}
看起来它是一个只有一个数组的对象/类(?)数组?我试图寻找 C 符号的含义,但没有成功。知道Transfer_Sales_Order_Item 的结构应该是什么样的吗?
我的猜测是因为原始类实现了ArrayAccess,但我尝试了它并且未序列化仍然抱怨它没有要反序列化的目标。
目前我们通过在类上实现Serializable 和unserialize() 方法来解决它,该方法将类的内容作为序列化字符串获取。然后,这通常会反序列化为一个数组,然后我们就从那里开始了。
这是我们用来反序列化字符串的代码:
class Transformer
{
public static function debugUnserialize($className)
{
throw new \RuntimeException(sprintf('Cannot unserialize object %s', $className, 500);
}
public function transform($value)
{
$previousCallback = ini_get('unserialize_callback_func');
ini_set('unserialize_callback_func', self::class . '::debugUnserialzie');
$data = unserialize($value);
ini_set('unserialize_callback_func', $previousCallback);
return $data;
}
}
添加空类Transfer_Sales_Order_Item后,PHP抛出
Warning: Class Transfer_Sales_Order_Item has no unserializer
请注意,这不是unserialize_callback_func 回调的例外情况。所以它甚至没有到达那里。
【问题讨论】:
-
@h2ooooooo 现在检查 - 使用换行符它不会反序列化过去
_data.... -
@MichaelBerkowski 看来你是对的!我已经删除了我的评论,因为这在这件事上毫无意义。 :)
-
简单地 preg_replace()'ing 所有额外的空格并没有帮助。
-
@h2ooooooo 反序列化会引发错误,因为它没有
C:25:"Transfer_Sales_Order_Item"的目标类。如果您添加Transfer_Sales_Order_Item,它仍然会抱怨没有目标并且没有将数组映射到的属性。非常令人费解。 -
@Adrian,
C:在 php 5.6 中被替换为O:,这意味着发回序列化的服务器是 php5.6 之前的。这意味着数据类型是需要unserialize_callback_func才能正确处理反序列化的对象。这是unserialize()上的文档,其中包含使用回调的示例
标签: php serialization