Формат не имеет спецификации за пределами реализации; Руководство PHP для unserialize() является ссылкой, и очевидно, что передача ненадежных входных данных небезопасна.
В первый раз, когда сериализованные данные PHP стоили мне полдня, это был билет службы поддержки WP. Настройки виджета панели управления пользователя пошли наперекосяк, и «настройки» они описывали жили в wp_options Таблица как единая сериализованная строка, похожая на линейное шум: a:4:{s:8:"_builtin";b:1;..., йо- Я не мог ее прочитать, я не мог с первого взгляда сказать, что не так, и я не хотел вкручивать полную среду PHP только для того, чтобы print_r один ряд. В тот день я забочусь о том, чтобы декодер был на одной вкладке браузера.
Если вы работаете в WordPress, WooCommerce, Laravel или любой другой кодовой базе PHP, вы встречались с сериализованными данными, хотите вы этого или нет. Он отображается в таблицах параметров, файлах сеансов, хранилищах кэша и мета-мете. И когда что-то ломается, возможность быстро читать это — это разница между пятиминутным исправлением и днем.
В этом руководстве рассматривается, что на самом деле является сериализованный формат, как его расшифровать с помощью несерийный инструмент на Toolz.dev, и - что немаловажно - единственное реальное ограничение, о котором вам нужно знать, прежде чем доверять выводам на неанглийских данных.
TL;DR: php
serialize()упаковывает значения в типизированную строку, напримерa:2:{s:4:"name";s:5:"Alice";...}где каждая часть несет свой тип и длину. выше Несериализируйте инструмент Анализирует это в вашем браузере и показывает это как дерево,print_r,var_dumpили JSON - нет PHP-сервера, нет загрузки данных. большое предостережение, которое я проверил сам: он считает длину строки в кодовых единицах UTF-16, а не байтах, поэтому сериализованные данные, содержащие акценты, смайлы или символы CJK, могут неправильно анализировать или не выполнять. Для данных ASCII он надежен. Он считывает данные; он не разрешает ссылки на объекты и не позволяет редактировать их на месте.
Что такое сериализация PHP, на самом деле?
Сериализация превращает значение PHP - массив, объект, строку, целое число и т. д. - в плоскую строку, которую вы можете сохранить в столбце базы данных или файле и позже перестроить unserialize(), йо- Две функции выполняют работу: serialize() преобразует значение в строку, unserialize() Преобразует обратно.
Что делает формат читаемым, когда вы знаете, что код, каждое значение объявляет его тип и размер. Вот весь словарный запас:
s:5:"hello" // string: s:length:"value"
i:42 // integer: i:value
d:3.14 // double: d:value
b:1 // boolean true (b:0 is false)
N; // null
a:2:{...} // array: a:count:{key;value;...}
O:8:"ClassName":1:{...} // object: O:namelen:"Class":propcount:{...}
Итак, сериализованный ассоциативный массив выглядит так:
a:3:{s:4:"name";s:10:"John Smith";s:5:"email";s:16:"[email protected]";s:4:"role";s:5:"admin";}
Это просто этот PHP-массив, упакованный плотно:
array(
'name' => 'John Smith',
'email' => '[email protected]',
'role' => 'admin'
)
Компактный для машины, почти нечитаемый для человека в 14:00 по звонку в службу поддержки. Вот и вся проблема, которую решает инструмент.
Как инструмент Toolz.dev unseerialize декодирует его?
Вы вставляете строку, и она анализирует формат непосредственно в JavaScript в вашем браузере и отображает результат. Я проверил каждый из них на собственном синтаксическом анализе инструмента во время написания этого, поэтому приведенное ниже поведение — это то, что он делает на самом деле, а не то, что предполагает руководство.
Последовательные массивы с целочисленными ключами возвращаются как реальный список. a:2:{i:0;s:5:"apple";i:1;s:6:"banana";} расшифровывается в ["apple", "banana"], йо- Ассоциативные массивы возвращаются в виде ключевых объектов. Вложенные структуры гнездятся правильно, массивы внутри массивов внутри объектов, полностью вниз.
Объекты сохраняют имя своего класса. O:4:"User":2:{s:4:"name";s:3:"Bob";...} Декодируется с __class__ маркер "User" плюс его свойства, так что вы можете видеть и тип, и данные. Он даже обрабатывает неловкий случай частных и защищенных свойств, которые PHP сериализует с нуль-байтовыми префиксами вокруг имени класса - инструмент удаляет их и показывает вам чистое имя свойства.
Вы получаете восемь выходных форматов для переключения между: древовидным представлением, print_r, var_dump, var_export, Крумо, FirePHP, DBUG и равнина JSON. Я живу в Tree View для изучения и JSON для копирования во что-то еще, но если ваша мышечная память ожидает var_dump Выход, он тут же.
Единственное ограничение, которое вам нужно знать: многобайтовые строки
Это та часть, которую я хотел бы, чтобы кто-то сказал мне, прежде чем я доверил декодеру производственным данным, так что здесь он заранее.
Сериализованный формат PHP измеряет длину строки в байт, йо- инструмент измеряет его в Длина строки JavaScrip, который учитывает кодовые единицы UTF-16. Для простого ASCII это один и тот же номер, поэтому английские данные отлично декодируются. В тот момент, когда строка содержит многобайтовый символ UTF-8, они расходятся.
Возьмем слово "Café." В UTF-8 """"" Étwo bytes, поэтому php сериализует его как s:5:"café" - длина пять, подсчет байтов. инструмент читает это 5 и берёт пять Кодовые единицы из струны, которая café" - он проглатывает заключительную цитату и теряет свое место. Я пробежал именно это: автономный s:5:"café"; Декодирует неверное значение, а внутри массива, например a:2:{s:1:"a";s:5:"café";s:1:"b";i:1;} он терпит неудачу с Unknown type ':' at position 25, йо-
Практический вывод: если вы отлаживаете параметры WordPress, которые являются чистыми ASCII - большинство настроек плагина, slugs, логические флаги - вы в порядке. Если сериализованные данные содержат акцентированные имена, эмодзи или текст CJK, декодирование может повредить или ошибиться, и это настоящая ошибка в инструменте, а не ваши данные. (Для записи исправление на нашем конце заключается в анализе по длине байта UTF-8, а не по длине байта UTF-8 .length;это в моем списке) Когда вы нажимаете, команды aware wp-clis сериализации на сервере являются надежными резервными копиями.
Существует соответствующее, более мягкое предостережение: var_dump Вывод отчетов сообщает длины строк, используя то же количество кодовых единиц, поэтому var_dump("café") спектакль string(4) где бы сказал настоящий php string(5), а эмодзи показывает длину, которая также не будет соответствовать количеству байтов PHP. Прочтите эти числа как "Длина JavaScript", а не "Длина байта php".
Зачем вам нужно отменять серийные данные за пределами PHP?
Множество причин, и почти ни одна из них не является "для развлечения».
Отладка — это большая. В отчете об ошибке говорится, что настройки пользователя неверны; настройки являются сериализованным двоичным объектом в базе данных; вы не сможете увидеть проблему, пока не расшифруете ее. Рабочий процесс, который я использую: SELECT option_value FROM wp_options WHERE option_name = 'widget_text';, скопируйте результат, вставьте его в Несериализируйте инструмент, и читаем дерево. Десять секунд по сравнению с написанием одноразового php-скрипта.
Миграции - это подлый. сериализованные строки встраивают свои собственные длины, поэтому наивный поиск и замена в дампе базы данных - скажем, замена старого домена на новый - изменяет содержимое строки без обновления префикса длины, и каждое затронутое значение становится несериализуемым. декодирование сначала показывает вам, какие именно значения несут домен, чтобы вы знали, какой простой поиск и замена сломается. (Правильный инструмент для самой замены - WP-CLI's search-replace, что понимает сериализацию.)
Затем есть проверка кэша и сеанса (Redis, Memcached и кэши файлов в приложениях PHP часто содержат сериализованные значения) и проверка безопасности, где вам нужно увидеть, что на самом деле хранится, прежде чем вы сможете судить, безопасно ли это.
Безопасно ли декодирование сериализованных данных в браузере?
безопаснее, чем делать это в PHP, и стоит понять, почему.
Родной PHP unserialize() Имеет долгую историю безопасности. Подача созданной строки, она может создавать экземпляры произвольных объектов и вызывать их магические методы (__wakeup, __destruct), который при правильных условиях становится атакой объекта и, в худшем случае, удаленным выполнением кода. Вот почему постоянный совет - никогда не звонить unserialize() на ненадежный вход и проходить ['allowed_classes' => false] когда ты должен.
Инструмент браузера оборачивает все это, потому что он никогда учащенные PHP. Он считывает формат строки и отображает структуру - никакие объекты PHP не создаются, никакие магические методы не срабатывают, и нет интерпретатора, которым можно было бы воспользоваться. Данные также остаются на вашем устройстве; он анализируется локально и никогда не отправляется на сервер, что имеет значение, когда сериализованная капля является сеансом или чем-то еще, что вы предпочитаете не загружать. Так для инспектирующий Ненадежные сериализованные данные, браузер действительно является более безопасным местом.
Родной PHP unserialize() |
Инструмент для браузера Toolz.dev | |
|---|---|---|
| создает экземпляры объектов | Да (риск впрыска) | Нет - читает только структуру |
| работает на сервере | да | Нет - локально в браузере |
| Безопасно при ненадежном введении | только с allowed_classes |
Да, он никогда не выполняется |
| Обрабатывает многобайтовую длину | Правильно (байты) | Ненадежно (кодовые единицы) |
| разрешает ссылки на объекты | да | Нет - шоу [Reference] |
| определенный | Восстановление живых ценностей | Осмотрите и прочитайте |
Эта таблица также является честным резюме компромиссов: инструмент браузера — это безопасный считыватель, а не замена языка.
Какие есть распространенные источники в реальном мире?
Если вы здесь, то, вероятно, это один из них. WordPress сильно опирается на сериализацию wp_options -- widget_text, sidebars_widgets, theme_mods_*, список активных плагинов, расписания cron. WooCommerce хранит вариации продуктов, атрибуты и настраиваемые поля как серийные меты, поэтому продукт с неправильными ценами часто восходит к сериализованному значению. Laravel использует сериализацию для кэша файлов и хранилища сеансов. Система конфигурации Magento заполнена этим. Везде один и тот же формат, один и тот же подход к декодированию.
Пара вещей, которые инструмент не делает
Две честные границы. не разрешает ссылки - PHP может сериализовать указатель на более раннее значение (r: или R:), а инструмент показывает их как буквальный [Reference] маркер, а не следование им. И это читатель, а не редактор: нет & quot;изменить это значение и повторно сериализовать& quot; режим. чтобы изменить сериализованные данные, декодировать их, внести изменение в PHP или в JSON, и повторно сериализовать на стороне PHP. Если вам необходимо вручную отредактировать необработанную строку, помните, что вам также необходимо исправить префиксы длины, и - согласно разделу выше - считать байты, а не символы.
Часто задаваемые вопросы
Для чего используется сериализация PHP?
Он преобразует сложные значения, такие как массивы и объекты, в единую строку, которая может жить в столбце базы данных, файле или кэше, а затем перестраивается. WordPress, WooCommerce, Laravel и Magento активно используют его для настроек, данных сеанса и кэшированных значений.
Могу ли я отменить серийность данных PHP без сервера PHP?
да. выше Несериализируйте инструмент Парсирует сериализованный PHP в JavaScript в вашем браузере. Нет установки PHP, нет сервера, нет учетной записи.
Безопасно ли декодировать сериализованные данные в браузере?
Да, и это безопаснее, чем собственное PHP. unserialize() При ненадежном вводе, потому что инструмент читает только строковую структуру. Он никогда не создает экземпляры PHP-объектов, поэтому атаки магического метода, которые делают нативные unserialize() Опасного просто не может быть.
Почему моя сериализованная строка не может декодировать?
Обычные причины — усеченная копия (вы пропустили скобки или первый символ), префикс длины после находки и замены или данные, которые на самом деле не сериализованы PHP. Еще один, который ловит людей: если строка содержит акцентированные символы, эмодзи или текст CJK, то подсчет длины кодового модуля инструмента может неправильно разобрать его, поскольку php считает длину строки в байтах, а инструмент подсчитывает единицы UTF-16.
Могу ли я декодировать значения wp_options с ним WordPress?
Да - это одно из самых распространенных применений. Запросить option_value, вставьте его и прочитайте структуру. Просто имейте в виду, что если опция содержит многобайтовый текст, вам может понадобиться WP-CLI на сервере.
Могу ли я редактировать сериализованные данные с помощью этого инструмента?
Нет, это читатель. Чтобы изменить значение, расшифровать его, изменить в PHP или JSON и повторно выполнить серийность на стороне PHP. Ручная редактирование необработанной строки означает самостоятельно фиксировать префиксы длины байта, что подвержено ошибкам.
В чем разница между сериализацией PHP и JSON?
Сериализация сохраняет специфичные для PHP типы, включая имена классов объектов и частные свойства. JSON не зависит от языка и знает только строки, числа, логические значения, null, массивы и объекты. Новый код обычно предпочитает JSON, потому что json_decode() Не создает экземпляры объектов, поэтому он позволяет избежать риска внедрения, а JSON можно читать повсюду. Вы можете переместить декодированную структуру в Форматтер JSON работать с ним таким образом.
Инструмент обрабатывает сериализованные объекты, а не только массивы?
да. Объекты декодируются с именем их класса, сохраненными рядом со свойствами, а частные или защищенные свойства (которые php сериализуются с префиксами нулевого байта) в выходных данных очищаются до читаемых имен.
заключение
Сериализованные данные PHP неизбежны, если вы коснетесь WordPress, WooCommerce или Laravel, а возможность читать их по запросу превращает категорию разочаровывающих ошибок в быстрые. выше Несериализируйте инструмент делает это на вкладке браузера, безопасно, без PHP-сервера - пока вы знаете его одно реальное ребро: многобайтовые строки могут споткнуться счет длины, и ASCII данные там, где он светит. вставить, прочитать, исправить. и когда данные полны акцентов или эмодзи, вместо этого обратитесь к WP-CLI.
Связанные инструменты:



