
PHP Unserialize: Decode WordPress Options and Serialized Data
Unserialize WordPress `wp_postmeta`, PHP sessions and Laravel caches to readable JSON in the browser — arrays and scalars only, no local script.
Decode serialized PHP instead of reading raw tokens
A WordPress option_value, a wp_postmeta.meta_value, a PHP session blob or a Laravel cache dump often lands in your editor as a:3:{s:8:"blogname";…}. That string is the output of PHP serialize(). It is not JSON and not a minified bundle. The online PHP unserializer turns array and scalar tokens into readable JSON (or PHP array syntax) in the browser. It does not run PHP, does not instantiate class objects and does not upload the payload. This article covers the debugging workflow: where these blobs live, how to paste them safely and when you still need native PHP. For the wire format, JSON versus serialize and object injection, start with the PHP serialization guide. Front-end assets on the same WordPress site are a separate job, covered in WordPress minification.
Serialize and unserialize, two tools for one WordPress dump
PHP serialize() emits a typed string. unserialize() rebuilds the value. FastMinify mirrors that split: php-serialize encodes JSON or PHP array syntax into a:/s:/i: tokens; php-unserialize decodes those tokens. Do not paste a serialized blob into the serializer, and do not paste JSON into the unserializer. Developer utilities that sit next to these pages live on the developer utilities hub.
a:…, s:…, i:…, d:…, b:…, N;array(…) / => syntax (see PHP serialize online)Core and many plugins call maybe_serialize() / maybe_unserialize(). If the value is a PHP array (or an object), it is stored in MySQL as a serialized string. Scalars (plain strings, numbers) stay as they are, so not every row has an a: prefix.
wp_options.option_value: site name, permalink structure, widget instances, plugin settingswp_postmeta.meta_value: attachment sizes, custom fields, page builderswp_usermeta / wp_commentmeta: same pattern, per user or comment_transient_* options) often hold an array, while the expiry time sits in a separate timeout optionO: followed by a class name, FastMinify rejects it, because that is an object, not an arrayIn PHP, unserialize() on untrusted input can instantiate objects and run gadget chains (object injection). FastMinify parses the format in JavaScript. It never executes PHP, and it does not decode O: class objects or R: references. That is a limit and a safety property. Use it to inspect array dumps. Do not treat a successful decode as “this payload is safe to unserialize in production”.
unserialize($s, ['allowed_classes' => false]) (PHP 7+)eval or wp-cli eval a blob you copied from a ticketWhat the parser accepts and what WordPress rows look like
Each token starts with a letter. FastMinify’s unserializer accepts the same subset it can serialize: null, bool, int, float, string, nested array. Objects and references are errors, not silent skips.
Before
After
a:N:{…}: array with N key/value pairs (associative or indexed)s:n:"…" is a string, where n is the byte length, not the character count of multibyte UTF-8i: integer, d: float, b:0/b:1 bool, N; nullO:8:"stdClass" and R: / r: are not decoded heres:3:"hello" without its closing semicolon, fails instead of corrupting the rest of the array. The tool does not compare the number with the text, so check it in PHP when it mattersAttachment metadata and some custom fields (ACF relationship or checkbox fields, for example) are arrays of integers and strings, exactly the subset this parser handles. Paste the cell, click Unserialize and copy the JSON.
Before
After
wp option get … --format=json already unserializes in PHP, so use FastMinify when you only have the SQL dumpPHP session files and some Laravel cache drivers store serialize() payloads. If the value is an array of scalars, the browser tool works. If it is an Eloquent model, a Carbon instance or any O: class, FastMinify returns a clear error. That is expected: the tool does not pretend to be PHP’s unserialize.
Cache::put of a plain array usually gives a:, so paste and decode itO:, so decode them in PHP with an allowlist, not hereencrypt() payloads are not serialize() output, so decrypt them in the app firstO:, no R:, no object executionUnserializing in the browser with a concrete WordPress example
Open the PHP unserializer, paste a single serialized string and click Unserialize. The output is JSON by default (indent 2, spaces). Switch to PHP array syntax if you are pasting back into a snippet. Everything stays in the tab, with no account and no server round-trip.
A sidebar widget shows empty after a migration. The widget_* option is a serialized array. You need to see which keys survived, not guess from a 400-character cell.
1. Copy the raw option_value
From SQL or WP-CLI, copy the full string starting at a:. Truncated previews ending in … will fail to parse.
2. Paste into php-unserialize
Open php-unserialize and leave the output on JSON. If you see an error about an unknown format at O:, the widget stored an object. Stop here and use PHP with allowed_classes.
3. Edit the JSON and re-serialize only if you must write back
Fix the keys in the JSON, then encode it again with php-serialize. This round-trip works for the arrays and scalars this parser supports. It does not give a byte-identical copy of WordPress’s original string (key order, spaces). Prefer WP-CLI wp option update with JSON when you can.
Redis shows a value that starts with a:. You want to know which config keys are in the payload before you delete the key.
1. Copy the value as raw text
redis-cli escapes the quotes inside a value unless you use its raw output mode, so copy the value as raw text. If anything sits before the first a: or s:, such as the expiry timestamp that the Laravel file cache driver writes first, cut it.
2. Decode locally
Paste it into the unserializer. Nested arrays become JSON objects or arrays. Nulls stay if “Include null values” is on (the default).
3. Leave object payloads to PHP
An Illuminate\… class token will raise an error. That is the tool working as documented, not a broken Redis dump.
When you still need PHP (and how to round-trip arrays)
If the blob contains objects, or you are in a deployment script, decode in PHP without instantiating classes. Incomplete class objects tell you the class name without running constructors. FastMinify does not replace this safeguard.
Basic example
Core already knows the format. maybe_unserialize() returns arrays as arrays, and WP-CLI prints JSON so you never edit length numbers by hand. Use FastMinify when you only have a SQL export or a paste from a ticket. Then write back through the WordPress APIs rather than a raw UPDATE of a tweaked serialize() string.
Basic example
Decode with php-unserialize, edit the JSON and encode with php-serialize. Nested JSON objects become PHP arrays, not O: objects. Sorting keys or stripping nulls and empty structures changes what you write back. The on-page docs say it plainly: this is not a byte-accurate WordPress SQL migration utility. For CSS and JS on the same site, use the WordPress minification guide, which is a different pipeline.
Basic example
Conclusion
Paste the serialize() string, read the JSON and decide whether the payload is an array you can round-trip or an object that belongs in PHP. FastMinify runs that inspection locally and refuses O:/R:. It is not unserialize(), not WP-CLI and not a safe find-and-replace on MySQL dumps. For the format in depth, keep the PHP serialization guide next to this workflow.
Decode a WordPress or session blob now
Related Articles

HTTP/2 and HTTP/3 change how files travel, not how big they are. Measured sizes, compile times and bundling tests show what minification still saves.

Convert a Unix epoch to a readable date and back, tell seconds from milliseconds, and avoid time zone, JWT and clock change traps, all in your browser.

Read a cron expression field by field, check its next runs in UTC or local time and avoid traps with steps, time zones and dialects, all in your browser.