
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.
Why decode serialized PHP instead of staring at a:3:{…}?
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 PHP serialize() — not JSON, 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 is the debug workflow: where those blobs live, how to paste them safely, and when you still need native PHP. For the wire format, JSON vs serialize, and object-injection theory, start with the PHP serialization guide. Front-end assets on the same WordPress site are a different job — see WordPress minification.
Serialize vs unserialize: two tools, 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 onlineCore and many plugins call maybe_serialize() / maybe_unserialize(). If the value is a PHP array (or an object), it is stored as a serialize() string in MySQL. Scalars (plain strings, numbers) stay as-is — you will not see a: prefixes on every row.
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 wrap an array with a timeoutO: plus a class name, FastMinify will reject it — that is a plugin 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:"…" — string; n is the byte length, not the character count for multibyte UTF-8i: integer, d: float, b:0/b:1 bool, N; nullO:8:"stdClass" and R: / r: — not decoded heres:3:"hello") fail instead of corrupting the rest of the arrayAttachment metadata and many ACF-style fields are arrays of integers and strings — exactly the subset this parser handles. Paste the cell, unserialize, copy JSON.
Before
After
wp option get … --format=json already unserializes in PHP — 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 product does not pretend to be PHP’s unserialize.
Cache::put of a plain array: usually a: — paste and decodeO: — decode in PHP with an allow-list, not hereencrypt() payloads are not serialize() — decrypt first in the appO:, no R:, no object executionUnserialize in the browser: a concrete WordPress loop
Open the PHP unserializer, paste a single serialized string, click Unserialize. 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 — no account, 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.
Step 1: copy the raw option_value
From SQL or WP-CLI, copy the full string starting at a:. Truncated previews with … will fail to parse.
Step 2: paste into php-unserialize
Open php-unserialize. Leave 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.
Step 3: edit JSON, then re-serialize only if you must write back
Fix keys in JSON. Encode again with php-serialize. This round-trip is for arrays/scalars this parser supports — it is not byte-identical to 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 flushing the key.
Step 1: copy the payload without the Redis length prefix
If the driver wraps serialize() in a Laravel prefix, strip the application prefix until the first a: or s:.
Step 2: decode locally
Paste into the unserializer. Nested arrays become JSON objects or arrays. Nulls stay if “include null values” is on (default).
Step 3: leave O: payloads to PHP
A Illuminate\… class token will 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 deploy script, decode in PHP without instantiating classes. Incomplete class objects tell you the class name without running constructors. FastMinify does not replace this gate.
Basic example
Core already knows the format. maybe_unserialize() returns arrays as arrays. WP-CLI prints JSON so you never hand-edit length prefixes. Use FastMinify when you only have a SQL export or a paste from a ticket — then write back through WP APIs, not a raw UPDATE of a tweaked serialize() string.
Basic example
Decode with php-unserialize, edit JSON, encode with php-serialize. Nested JSON objects become PHP arrays, not O: objects. Sorting keys or stripping nulls/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/JS on the same site, stay on the WordPress minification guide — that is a different pipeline.
Basic example
Conclusion
Paste the serialize() string, read JSON, decide whether the payload is an array you can round-trip or an object that belongs in PHP. FastMinify runs that inspect locally and refuses O:/R:. It is not unserialize(), not WP-CLI, and not a safe find-replace on MySQL dumps. For the format deep-dive, keep the PHP serialization guide next to this workflow.
Related Articles

Stages, includes, `rules:`: structurally validate a .gitlab-ci.yml before the pipeline runs — not a GitLab runner, not official CI Lint.

Broken YAML, missing `on` or `jobs`, empty steps: structurally validate workflows before you push — and keep actionlint in CI.

SDL syntax errors, schema review and formatting before merge — extends the existing GraphQL beautifier.