Signature
serialize(mixed $value): stringPurpose
serialize() converts a PHP value into a string that records both the data and its type. You can keep that string in a cache entry, queue message or database column, and later rebuild the value with unserialize(). Unlike a plain (string) cast, the result keeps the difference between 42 and "42", between false and null, and the full shape of nested arrays.
Signature
Parameters
$value is the only parameter and has no default. It accepts any type except resources, and some objects cannot be serialized either. Arrays and objects are walked recursively. Circular references inside the structure being serialized are preserved. Any other reference is lost, so two variables that were bound by reference come back as independent values.
Return value and failures
The function returns a string. The manual stresses that it is a binary string that may contain null bytes, so store it in a BLOB-style column rather than a CHAR or TEXT field. Strings are recorded with their length in bytes, not characters.
The string format is compact. i:42; is an integer, b:1; is true, d:3.5; is a float, N; is null, and s:5:"..."; is a five-byte string. Arrays start with a: and a count, and objects start with O:, the class name length and the class name.
Built-in objects that implement none of Serializable, __serialize()/__unserialize() or __sleep()/__wakeup() cannot reliably be serialized. In that case, expect an error instead of a usable string. Closures are a common example.
Example 1: scalar values
Each type has its own prefix. Note that café is five bytes in UTF-8 because é takes two.
echo serialize(true), "\n";
echo serialize(42), "\n";
echo serialize(3.5), "\n";
echo serialize("café"), "\n";
echo serialize(null), "\n";b:1; i:42; d:3.5; s:5:"café"; N;
Example 2: a round trip with an array
Nested arrays keep their keys, order and value types. Because the types are preserved, a strict comparison after unserialize() succeeds.
$data = ['id' => 7, 'tags' => ['php', 'json'], 'active' => false];
$text = serialize($data);
echo $text, "\n";
var_dump(unserialize($text) === $data);a:3:{s:2:"id";i:7;s:4:"tags";a:2:{i:0;s:3:"php";i:1;s:4:"json";}s:6:"active";b:0;}
bool(true)
Example 3: controlling object output
When an object defines __serialize(), PHP calls it and serializes the returned array. This lets you choose exactly which data is stored, and avoids the null-byte prefixes that private and protected property names otherwise receive. The matching __unserialize() receives that array when the value is restored.
final class Point
{
public function __construct(private int $x, private int $y) {}
public function __serialize(): array
{
return ['x' => $this->x, 'y' => $this->y];
}
public function __unserialize(array $data): void
{
$this->x = $data['x'];
$this->y = $data['y'];
}
}
echo serialize(new Point(3, 4)), "\n";O:5:"Point":2:{s:1:"x";i:3;s:1:"y";i:4;}
Edge cases
- Private and protected properties: without
__serialize(), a private property name is prefixed with the class name and a protected one with*, each surrounded by null bytes. Printing or copying such a string as text can corrupt it. - Namespaced classes: the leading backslash is left out of the stored class name for compatibility.
- Byte lengths: the number in
s:N:counts bytes. Editing a serialized string by hand, or converting its encoding, breaks it. - References: only circular references within the serialized structure survive. Other reference relationships are flattened into copies.
- Resources: database connections, file handles and similar values cannot be stored. Store the information needed to reopen them instead.
Common mistakes
- Using it as an interchange format. The format is PHP-specific. If other languages must read the data,
json_encode()is usually a better choice. - Calling
unserialize()on untrusted input. Restoring attacker-controlled strings can instantiate classes and trigger magic methods. Prefer JSON for external data, or restrict classes with theallowed_classesoption ofunserialize(). - Storing the result in a text column. Null bytes and byte-oriented lengths make
TEXTstorage unreliable. Use a binary-safe column. - Expecting references to survive. Do not rely on shared references being rebuilt after a round trip.
- Serializing live objects wholesale. Objects holding connections, closures or large caches should limit their stored state with
__serialize()or__sleep(). - Treating the format as stable across class changes. If you rename a class or change its properties, previously stored strings may no longer restore as you expect. Plan a migration.
Related functions
unserialize()rebuilds a PHP value from the string.json_encode()produces portable text for arrays and simple objects.var_export()returns parsable PHP code for a value.- The magic methods
__serialize(),__unserialize(),__sleep()and__wakeup()customize object behavior.
Recap
serialize(mixed $value): string produces a type-preserving, binary-safe string for nearly any PHP value. It keeps nested structure and circular references but not ordinary references, and it cannot handle resources or some built-in objects. Use __serialize() to control object contents, store the output in a binary-safe place, and never unserialize untrusted data without strict safeguards.
Tested examples
echo serialize(true), "\n";
echo serialize(42), "\n";
echo serialize(3.5), "\n";
echo serialize("café"), "\n";
echo serialize(null), "\n";b:1; i:42; d:3.5; s:5:"café"; N;
$data = ['id' => 7, 'tags' => ['php', 'json'], 'active' => false];
$text = serialize($data);
echo $text, "\n";
var_dump(unserialize($text) === $data);a:3:{s:2:"id";i:7;s:4:"tags";a:2:{i:0;s:3:"php";i:1;s:4:"json";}s:6:"active";b:0;}
bool(true)
final class Point
{
public function __construct(private int $x, private int $y) {}
public function __serialize(): array
{
return ['x' => $this->x, 'y' => $this->y];
}
public function __unserialize(array $data): void
{
$this->x = $data['x'];
$this->y = $data['y'];
}
}
echo serialize(new Point(3, 4)), "\n";O:5:"Point":2:{s:1:"x";i:3;s:1:"y";i:4;}