У меня есть эта строка в базе данных.
Мне нужно десериализовать его с помощью php.
Проблема в том, что он возвращает некоторые объекты «__PHP_Incomplete_Class_Name».
Я знаю, что эта строка была сериализована со старым расширением MongoDB PHP, и я пытаюсь десериализовать с более новым расширением MongoDB.
Таким образом, MongoId и MongoDate устарели.
Это строка:
$string = 'a:2:{i:0;a:3:{s:4:"name";s:52:"----------------------------------------------------";s:6:"amount";s:5:"53.09";s:10:"service_id";s:24:"------------------------";}i:1;a:6:{s:2:"id";C:7:"MongoId":24:{5b2276372a4ef288038b45ba}s:4:"name";s:21:"---------------------";s:4:"type";s:8:"one time";s:10:"service_id";s:20:"thisrhietingcfffffff";s:6:"amount";s:6:"139.29";s:10:"added_date";O:9:"MongoDate":2:{s:3:"sec";i:1528985143;s:4:"usec";i:917000;}}}';
Когда я делаю:
$result = @unserialize($string);
var_dump($result);
Результат:
array(2) {
[0]=>
array(3) {
["name"]=>
string(52) "----------------------------------------------------"["amount"]=>
string(5) "53.09"["service_id"]=>
string(24) "------------------------"}
[1]=>
array(6) {
["id"]=>
object(__PHP_Incomplete_Class)#1 (1) {
["__PHP_Incomplete_Class_Name"]=>
string(7) "MongoId"}
["name"]=>
string(21) "---------------------"["type"]=>
string(8) "one time"["service_id"]=>
string(20) "thisrhietingcfffffff"["amount"]=>
string(6) "139.29"["added_date"]=>
object(__PHP_Incomplete_Class)#2 (3) {
["__PHP_Incomplete_Class_Name"]=>
string(9) "MongoDate"["sec"]=>
int(1528985143)
["usec"]=>
int(917000)
}
}
}
Я попытался class_alias MongoId для ObjectId. Не работает.
Я попытался создать новый класс MongoId для расширения ObjectId. Мне не разрешено, потому что ObjectId является последним классом.
Я попытался заменить C: 7: «MongoId» на C: 8: «ObjectID».
Результат тот же: __PHP_Incomplete_Class_Name
Может быть, есть возможность вернуть результат как массив, а не как объект?
Ваш подход указывает правильное направление для MongoDate, потому что он использует обычную сериализацию O-типа. Для MongoId это сложнее, поскольку он имеет собственные обработчики сериализации C-типа.
Если бы это было моей задачей, я бы начал примерно так:
Объявить класс MongoId
и реализовать интерфейс Serializable. Для unserialize
Функция пытается имитировать оригинальную функцию (доступно здесь на L407-> L220).
Для serialize
Функция выяснить, что ObjectId
Сериализация выглядит и подражает. (Имеется в наличии здесь L187)
десериализацию строки из базы данных и сериализацию снова.
Замените C: 7: «MongoId» на C: 21: «MongoDb \ BSON \ ObjectID» в повторно сериализованной строке. Вам нужно пространство имен вместе с именем класса.
снова несериализовать и молиться.
Класс MongoId должен выглядеть примерно так; но код вообще не тестируется:
class MongoId implements Serializable {
public $id;
public function serialize() {
return serialize(['oid' => $this->id]);
}
public function unserialize($str) {
$this->id = $str;
}
}
Надеюсь, это поможет хоть немного.
В зависимости от ваших потребностей может быть проще просто определить классы. Тогда будет unserialize
просто хорошо. Это десериализует значение объекта, который реализован Serializable
обозначается C
в C:7:"MongoId"
как id
в несериализованном объекте:
class MongoId implements Serializable {
public function unserialize($str) {
$this->id = $str;
}
public function serialize() {}
}
class MongoDate {}