1. Home
  2. 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.

ExampleMeaning
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:

  1. A string length that does not match. A search-and-replace changed http://old.com to https://new-domain.com without updating s:14:. Count the bytes of the new value and update the number, or re-serialize the data.
  2. 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.
  3. Truncated data. The column was too short, for example VARCHAR(255), and the end of the string was cut off. Use TEXT or LONGTEXT.
  4. 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

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.