API / Minn\Support / Serialized

Serialized final class

Minn\Support\Serialized · public/minn/src/Minn/Support/Serialized.php · 356 lines

Tolerant readers for the serialized-PHP blobs WordPress stores. Nothing here executes the blob; each reader scans for the one shape it needs.

Constants and properties

constINVALID = '' . "\0" . 'minn:invalid' . "\0" . ''

Returned by decode() when the blob is not a serialized value the reader accepts.

privateMAX_DEPTH = 4096

The deepest nesting a record may have, PHP's own default (unserialize_max_depth).

privateSMALLEST_PAIR = 6

The fewest bytes an array or object member can take: a key "i:0;" and a value "N;".

privatestatic ?WeakMap $records
privatestatic ?SplObjectStorage $open

The objects being encoded right now, outermost first, so a loop is seen.

privatestatic int $depth

Public

staticstringList(?string $blob): array#

The string values of a serialized string list.

staticserializeStringList(array $values): string#

A flat string list in the stored form.

staticfield(?string $blob, string $field): ?string#

The first "field";value pair inside a blob: string, int, or float value as a string.

staticdecode(string $blob, ?Closure $revive = NULL): mixed#

A serialized scalar or array as PHP data, parsed by this reader: strings, integers, floats, booleans, null, and arrays of those. An object record becomes a stdClass of its properties, or whatever the reviver makes of the class name and those properties; nothing here instantiates anything itself. A blob with trailing bytes or a malformed shape is INVALID.

$revive?\Closure(string, \stdClass): object
staticstoredClass(object $object): ?string#

The class an object was stored as, when it came back as a stdClass of its properties.

staticlooksSerialized(string $data): bool#

Whether a string has the shape of serialized data, as is_serialized() judges it: what maybe_serialize() stores serialized again so it reads back as the string it was.

staticencode(mixed $value): string#

PHP's serialize() for the values decode() accepts: null, bool, int, float, string, arrays of those, and objects written as their class.

staticintList(?string $blob): array#

The integer values of a serialized list such as sticky_posts.

Internals 10

Private and protected methods: how the class does its work. Not a contract; they change whenever the code is tidied.

privateread(string $blob, int $offset, ?Closure $revive): mixed#
privatereadValue(string $blob, int $offset, ?Closure $revive): mixed#
privatereadObject(string $blob, int $offset, ?Closure $revive): object#

An object record. The properties land on a plain stdClass; only the reviver may turn that into something else, and only for a class it knows. A record it leaves alone keeps its class name and its stored property names (visibility markers, numbered parts, a private name a parent class shares) on the side, so encode() writes it back as it was read instead of as a stdClass.

privateencodeRecord(object $object, array $record): string#

A stdClass, or a record read back as one, in PHP's own form: the stored class name and property names where there are some, property names as strings otherwise, each value through encode() so a record nested inside keeps its class too.

$recordarray{class: string, keys: array<string, int|string>, hidden: list<array{0: int|string, 1: mixed}>}
privateencodeWrapper(ArrayObject|ArrayIterator $wrapper): string#

PHP's array wrappers in their own form (flags, storage, members, iterator class), the storage through encode().

privateexpect(string $blob, int $offset, string $char): void#
privatesize(string $blob, int $offset, string $char, int $perItem): int#

A length or a count: digits only, and never more than the bytes left could hold, $perItem bytes each. A negative length would move the reader backwards and a huge count would keep it reading, so either makes the record no record at all, as PHP's own reader finds it.

privateuntil(string $blob, int $offset, string $char): string#
privateencodeValue(mixed $value): string#
privateencodeObject(object $value): string#

Plugin code stores objects (maybe_serialize's contract). A record read back as a stdClass is written under the class it was stored as; a stdClass and PHP's array wrappers are written here so a record inside them keeps its class too; any other object goes through PHP's own serializer, which runs nothing and matches the reference byte for byte. Only reading is the hazard, and reads stay on decode().