- Home
- PHP Unserialize
PHP Unserialize
Paste serialized PHP data and read it as a tree, JSON, print_r or var_export. Or go the other way and serialize JSON with correct byte lengths.
Parsed in your browser. No class code is ever executed.
How to read PHP serialized data
The format written by serialize() is compact but readable once you know the pattern: a type letter, a colon, then the value, ending with a semicolon or a block in braces.
| Example | Meaning |
|---|---|
| N; | null |
| b:1; | Boolean true (0 is false) |
| i:42; | Integer |
| d:3.14; | Float |
| s:5:"hello"; | String; the number is its length in bytes |
| a:2:{…} | Array with 2 elements; keys and values alternate |
| O:8:"stdClass":1:{…} | Object of class stdClass with 1 property |
| E:11:"Suit:Hearts"; | Enum case (PHP 8.1+) |
| r:2; R:2; | Reference to an earlier value |
Inside an object, protected property names start with \0*\0 and private ones with \0ClassName\0, where \0 is a null byte. Those bytes are invisible in most editors and often lost when data is copied, which is another common reason for “Error at offset”. The tree view labels such properties as protected or private.
Fixing “unserialize(): Error at offset”
PHP stops at the first byte that does not fit the format. The usual causes, in order:
- A string length that does not match. A search-and-replace changed
http://old.comtohttps://new-domain.comwithout updatings:14:. Count the bytes of the new value and update the number, or re-serialize the data. - Character encoding changed. “é” is 1 byte in Latin-1 and 2 bytes in UTF-8. Converting a database dump between encodings breaks every length that contains such characters.
- Truncated data. The column was too short, for example
VARCHAR(255), and the end of the string was cut off. UseTEXTorLONGTEXT. - Escaped quotes. The data went through
addslashes()twice, so"became\". Strip the extra backslashes first.
serialize() or json_encode()?
For new code, prefer JSON. json_encode() output is readable by every language, safe to decode from untrusted sources, and easy to query in MySQL and PostgreSQL. serialize() is only worth it when you must store PHP objects with their class, and even then __serialize() and __unserialize() (PHP 7.4+) give you control over what is stored. You can compare both functions in the PHP Sandbox, and convert between JSON and PHP arrays with the JSON to PHP Array converter.
More PHP tools
PHP Version Checker
Find the PHP version of any website, or which versions your code runs on.
PHP Sandbox
Write and run PHP 7.4 to 8.5 in your browser. Nothing to install.
PHP Syntax Checker
Find parse errors with the exact line, checked by the real PHP parser.
PHP EOL Dates
Support and end-of-life dates for every PHP version, with countdowns.
Bcrypt Generator
Hash and verify passwords in the format PHP's password_hash() uses.
phpinfo() Analyzer
Paste phpinfo() output and see risky settings and outdated versions.
PHP Date Format
Every date() format character with a live preview of your format string.
PHP Formatter
Beautify PHP code to the PSR-12 style in one click.
PHP Regex Tester
Test preg_match, preg_replace and preg_split with real PHP PCRE.
JSON to PHP Array
Convert JSON to a PHP array and PHP arrays back to JSON.
Frequently asked questions
What does PHP unserialize do?
unserialize() turns a string created by serialize() back into a PHP value: arrays, objects, strings, numbers and so on. Serialized strings are common in WordPress options and post meta, Laravel cache and session files, and older applications that store arrays in a single database column.
Why does unserialize() fail with “Error at offset”?
Almost always because a string length is wrong. In s:5:"hello"; the 5 is the length in bytes. If someone edited the data by hand, ran a search-and-replace on a database dump, or converted the character encoding, multi-byte characters change the byte count and the whole value becomes unreadable. This tool reports the byte where parsing stopped, so you can fix the length there.
Is it safe to unserialize data from users?
No. Unserializing untrusted input with classes allowed can trigger magic methods like __wakeup() and __destruct() and has led to many remote code execution bugs. Use json_decode() for data from outside, or at least pass ['allowed_classes' => false]. This tool parses the data with its own JavaScript parser and never executes any class code; the optional real-PHP check allows no class except stdClass, which has no code to run.
How do I edit a serialized WordPress option?
Unserialize it here, change the JSON, then use the Serialize tab to turn it back into a valid string with correct lengths. Better still, use WP-CLI: wp option get name --format=json and wp option update name --format=json handle the conversion for you. For domain changes, use a serialization-aware tool such as wp search-replace.
Is my data uploaded?
No. Parsing, conversion and the optional PHP check all run in your browser.