serialize
Converts any PHP value except resources into a storable byte-stream string.
serialize(mixed $value): string- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$value | mixed | The value to be serialized. serialize() handles all types except resource and some objects. |
Return value
stringA byte-stream representation of the value that can be stored anywhere.
Errors
Throws an Exception when asked to serialize a Closure, a Generator, or another object the engine forbids serializing.
Changelog
- PHP 7.4.0__serialize() and __unserialize() were added and take precedence over __sleep() and __wakeup() when defined.
serialize() turns almost any PHP value into a string that unserialize() can turn back into the exact same value — including object classes, private and protected properties, integer versus string types, and circular references. That fidelity is what it buys you over JSON.
When to reach for it
Use it for PHP-to-PHP round trips where type fidelity matters and nothing else needs to read the data: session payloads, cache entries, queued job state. If any other language, tool or human will read the value, use json_encode() instead — JSON is portable, inspectable, and indexable by most databases.
What trips people up
Never call unserialize() on data a user can influence. Unserializing attacker-controlled input can instantiate arbitrary classes and trigger their __wakeup() and __destruct() methods — a well-known remote-code-execution path. If you must, pass ['allowed_classes' => false] as the second argument, and prefer JSON with a signature.
The output is a binary string. Private properties are wrapped in \0ClassName\0 and protected ones in \0*\0, so storing it in a TEXT or VARCHAR column with a non-binary collation will silently corrupt it. Use BLOB, or base64_encode() the result.
Closures and generators cannot be serialized and throw. Resources such as file handles serialize to integer 0 and are useless afterwards.
Example
When to use it
- Caching a fully-typed PHP value where json_decode() would lose int/string distinctions
- Storing an object graph with private properties in a BLOB column
- Persisting queued job state that only PHP will ever read back
Frequently asked questions
What is the difference between serialize and json_encode?
serialize() preserves PHP types, object classes and private properties but is only readable by PHP; json_encode() produces portable text but loses class identity and can change numeric types. Use JSON unless you need exact PHP fidelity.
Is unserialize safe on user input?
No. Unserializing untrusted data can instantiate arbitrary classes and invoke their __wakeup() and __destruct() methods, a known remote-code-execution vector. Pass ['allowed_classes' => false] at minimum, or use JSON.
Why does my serialized object break when stored in the database?
Serialized data is a binary string containing null bytes around private and protected property names. Store it in a BLOB column or base64_encode() it before writing to a TEXT column.
More examples
serialize versus json_encode fidelity
serialize() round-trips identically. JSON writes 1.0 as 1 and reads it back as an int, so the strict comparison fails — a real source of bugs when money or ratios pass through a JSON cache.
<?php
$value = ['n' => 42, 's' => '42', 'f' => 1.0, 'nil' => null];
$viaSerialize = unserialize(serialize($value));
$viaJson = json_decode(json_encode($value), true);
var_dump($viaSerialize === $value);
var_dump($viaJson === $value);
var_dump(get_debug_type($viaJson['f']));
var_dump(get_debug_type($viaSerialize['f']));Controlling serialization with __serialize
__serialize() returns only the data worth persisting, dropping the live handle. __unserialize() rebuilds the transient state on the way back, which is why the restored object shows 'reopened'.
<?php
class Conn {
public function __construct(public string $dsn, public ?string $handle = 'open') {}
public function __serialize(): array { return ['dsn' => $this->dsn]; }
public function __unserialize(array $d): void {
$this->dsn = $d['dsn'];
$this->handle = 'reopened';
}
}
$s = serialize(new Conn('sqlite:memory'));
echo $s, "\n";
print_r(unserialize($s));
Discussion