PHP Unserialize: Decode WordPress Options and Serialized Data

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.

31.08.2026
9 min read
Share this article:
PHP
Unserialize
WordPress
Debugging
Serialization
Tutorial

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.

Inspect wp_options, postmeta and transients without a local PHP script
JSON or PHP array output, indent 2 spaces by default — nothing leaves the tab
Honest parser: arrays and scalars only — O: objects and R: references are rejected
Safer than PHP unserialize() on an unknown dump: no object execution
Round-trip arrays via php-serialize after you edit the readable JSON

Serialize vs unserialize: two tools, one WordPress dump

serialize() writes; unserialize() reads — FastMinify splits the pages

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.

Unserialize page: paste a:…, s:…, i:…, d:…, b:…, N;
Serialize page: paste JSON or array(…) / => syntax — see PHP serialize online
Output format on unserialize: JSON (default) or PHP array syntax
Pretty JSON is for reading; compact JSON is minify-json after you copy
A minified JS file from a plugin is not serialize(): use an online JavaScript unminifier
Where WordPress actually stores serialize()

Core 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 settings
wp_postmeta.meta_value — attachment sizes, custom fields, page builders
wp_usermeta / wp_commentmeta — same pattern, per user or comment
Transients (_transient_* options) often wrap an array with a timeout
If the cell starts with O: plus a class name, FastMinify will reject it — that is a plugin object, not an array
PHP unserialize() is a security boundary; the browser tool is not PHP

In 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”.

Unknown dump: inspect in the browser first — no upload, no PHP process
If you must decode in PHP: unserialize($s, ['allowed_classes' => false]) (PHP 7+)
Never eval or wp-cli eval a blob you copied from a ticket
Option dumps can contain API keys — a local tab is safer than a random online unserializer that posts to a server

What the parser accepts — and what WordPress rows look like

Type prefixes you will see in a typical option_value

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

a:3:{s:8:"blogname";s:10:"FastMinify";s:11:"description";s:22:"Local developer tools.";s:7:"WPLANG";s:5:"en_US";}

After

{ "blogname": "FastMinify", "description": "Local developer tools.", "WPLANG": "en_US" }
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-8
i: integer, d: float, b:0/b:1 bool, N; null
O:8:"stdClass" and R: / r:not decoded here
Broken length prefixes (s:3:"hello") fail instead of corrupting the rest of the array
wp_postmeta: a nested array you can actually read

Attachment 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

a:2:{s:5:"width";i:1200;s:6:"height";i:630;}

After

{ "width": 1200, "height": 630 }
phpMyAdmin / TablePlus: copy the raw cell, not the truncated preview
WP-CLI wp option get … --format=json already unserializes in PHP — use FastMinify when you only have the SQL dump
After decode, toolbar: JSON (default) vs PHP array syntax; indent size 2; spaces or tabs
Optional filters: drop nulls, empty arrays, empty objects, or sort keys — they change the payload, so leave them off for a faithful inspect
Need compact JSON for a ticket: online JSON minifier on the copied output
Sessions, Laravel caches, and the O: wall

PHP 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.

Laravel Cache::put of a plain array: usually a: — paste and decode
Laravel Eloquent / custom DTOs: O: — decode in PHP with an allow-list, not here
Encrypted cookies and encrypt() payloads are not serialize() — decrypt first in the app
igbinary or JSON cache stores are not PHP serialize() — look at the driver before pasting
Same honesty as the tool docs: no O:, no R:, no object execution

Unserialize in the browser: a concrete WordPress loop

Using the PHP unserializer

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.

Accepted tokens: N;, b:, i:, d:, s:, nested a: arrays
Rejected: O: class objects, R:/r: references, truncated or invalid length prefixes
Options: output JSON vs PHP array; include nulls (on by default); strip empty arrays/objects; sort keys; indent size and space vs tab
Not a WordPress SQL migration tool: do not find-replace s:n:"…" in a dump by hand
Scenario — a widget instance in wp_options

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

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.

2

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.

3

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.

Scenario — Laravel cache dump in Redis

Redis shows a value that starts with a:. You want to know which config keys are in the payload before flushing the key.

1

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

2

Step 2: decode locally

Paste into the unserializer. Nested arrays become JSON objects or arrays. Nulls stay if “include null values” is on (default).

3

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)

allowed_classes => false — the PHP-side inspect

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

<?php // Inspect an untrusted serialize() dump without instantiating classes (PHP 7+). $raw = file_get_contents('option_value.txt'); $value = unserialize($raw, ['allowed_classes' => false]); var_export($value);
WordPress: maybe_unserialize and WP-CLI

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

# Read an option as JSON (WordPress unserializes in PHP). wp option get widget_text --format=json # Update from a JSON file instead of patching s:n:\"…\" in SQL. wp option update my_plugin_settings "$(cat settings.json)" --format=json
Round-trip in the browser — arrays only

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

// Browser loop (arrays/scalars only): // 1. Paste serialize() string → php-unserialize → JSON // 2. Edit JSON // 3. Paste JSON → php-serialize → new a:… string // Do not UPDATE wp_options with a hand-edited s:n:"…" prefix.

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.

Copy the full cell — truncated a: strings fail to parse
Leave O: payloads to PHP with allowed_classes => false
Do not hand-edit s:n:"…" length prefixes in SQL
Round-trip arrays only: unserialize → JSON → serialize
Keep dumps in the browser; option_value can contain secrets
Share this article
Share this article: