2013-07-05 5 views
6

В PHP Мне очень трудно использовать serialize/unserialize на большом массиве объектов (100000+ объектов). Эти объекты могут быть разных типов, но все они являются потомками базового класса.PHP: массив объектов - serialize vs json_encode - альтернативы?

Как-то, когда я использую unserialize на массив объектов около 0,001% объектов сгенерированы неправильно! Вместо этого генерируется целый другой объект. Это не случается случайным образом, но каждый раз с теми же объектами. Но если я изменяю порядок массива, это случается с разными объектами, поэтому это выглядит как ошибка для меня.

Я переключился на json_encode/json_decode, но обнаружил, что в качестве класса объекта всегда используется stdClass. Я решил это, включив classname каждого объекта в качестве свойства, а затем с помощью этого свойства создайте новый объект, но это решение не очень элегантно.

Использование var_export с eval работает нормально, но примерно в 3 раза медленнее, чем другие методы, и использует гораздо больше памяти.

Теперь мои вопросы:

  • , что может привести к ошибке/неправильные объекты, которые создаются с unserialize?
  • есть лучший способ использовать json_decode с массивом объектов, чтобы классы каким-то образом сохранялись в json автоматически?
  • Возможно, есть еще один способ чтения/записи большого массива объектов в PHP?

UPDATE

Я начинаю верить, что должно быть что-то странное с моим массива данных, потому что с msgpack_serialize (расширение PHP, альтернатива serialize) я получаю такой же ошибки (но как ни странно не те же объекты генерируются неправильно!).

UPDATE 2

Найдено решение: вместо того, чтобы делать serialize на весь массив, я делаю это на каждом объекта теперь первым serialize, а затем base64_encode, а затем хранить каждый объект, преобразованный отдельную строку в текстовом файле. Таким образом я могу сгенерировать весь массив объектов, а затем повторить каждый объект, используя file() с unserialize и base64_decode: больше ошибок нет!

+0

какие именно ошибки появляются? – Robert

+0

как-то НЕКОТОРЫЕ из объектов, которые сгенерированы с unserialize, на самом деле представляют собой целый другой объект, который также находится в массиве, но который таким образом генерировал TWICE. Поэтому кажется, что что-то не так с некоторыми внутренними указателями на объекты ... – Dylan

+0

Проверить мой ответ Dylan serialize() лучше для больших объектов json_encode лучше для объектов, у которых нет ресурсов, и вам все равно, проснуться "должным образом. – Robert

ответ

3

С сериализованными/неэтериализованными функциями связаны магические методы.

__sleep()

сериализации() проверяет, является ли ваш класс имеет функцию с волшебным именем __sleep(). Если это так, эта функция выполняется до любой сериализации. Он может очистить объект и должен возвращать массив с именами всех переменных этого объекта, которые должны быть сериализованы. Если метод ничего не возвращает, NULL сериализуется и выдается E_NOTICE.

С сон у вас есть лучший контроль над сериализацией, вы можете передавать переменные, которые могут быть сериализованы и чистые ресурсы, обеспечивающие серализацию.

Когда десериализация вызывается, то другая функции следует отметить

__wakeup()

Предполагаемого использование __wakeup() является, чтобы восстановить любые базы данных соединений, которые могут быть потеряны в процессе сериализации и выполнение другой реинициализации задания.

О json_encode()

  1. Это не имеет магические методы __wakeup, __sleep поэтому у вас есть меньше контроля
  2. Это не сериализации частных свойств
  3. Объекты всегда хранятся в виде StdClass
  4. json_encode быстрее, чем сериализации

Это зависит от вас, что вы выберете, но для более продвинутых классов с подключением db и т. Д. Я бы предложил serialize()

Смежные вопросы