ValueSerializer#
ValueSerializer is a thin wrapper around Opis Closure v4 that adds
first-class support for PHP resources and now includes
transport-friendly helpers.
Under the hood it relies on:
Opis Closure’s
serialize()/unserialize()for closures, anonymous classes & deep object graphs.A plugin system (“resource handlers”) that can wrap any PHP resource into plain data and restore it on the way back.
A tiny memo-cache inside
Infocyph\InterMix\Serializer\ValueSerializer::isSerializedClosureto detect Opis payloads with O(1) string checks.
Why?#
Plain PHP serialize() chokes on closures *and* resources.
ValueSerializer solves both:
Closures & objects → delegated to Opis Closure.
Resources → you register wrap / restore callbacks.
Everything becomes a safe string, ready for caches, queues, cookies, etc.
Public API#
- string ValueSerializer::serialize(mixed $value)
Convert any PHP value into a binary string. Throws
InvalidArgumentExceptionif an un-handled resource is found.
- mixed ValueSerializer::unserialize(string $blob)
Reverse of
serialize()– returns the original value.
- string ValueSerializer::encode(mixed $value, bool $base64 = true)
– Convenience wrapper around
serialize(). If$base64is true (default) the binary blob is passed throughbase64_encode()– perfect for URLs, JSON, headers, etc.
- mixed ValueSerializer::decode(string $payload, bool $base64 = true)
– Rebuild a value produced by
encode(). Decodes base64 (when enabled) and forwards tounserialize().
- void ValueSerializer::setPayloadSigningKey(?string $key)
Configure HMAC payload signing/verification for
serialize()/unserialize()andencode()/decode().nulldisables signing checks (backward-compatible mode).non-null enables signed payload mode (HMAC-SHA256 envelope required on decode).
- bool ValueSerializer::isSerializedClosure(string $str)
Cheap Opis payload detector used by Invoker. Internally memo-cached for the lifetime of the request.
- mixed ValueSerializer::wrap(mixed $value)
Wrap resources only (no string conversion).
- mixed ValueSerializer::unwrap(mixed $value)
Reverse of
wrap().
- void ValueSerializer::registerResourceHandler(string $type, callable $wrapFn, callable $restoreFn)
Register a new resource handler.
- void ValueSerializer::clearResourceHandlers()
Drop all previously registered handlers (handy in tests).
Usage Examples#
Serialize / Unserialize#
use Infocyph\InterMix\Serializer\ValueSerializer;
$adder = fn (int $x) => $x + 10;
$stream = fopen('php://memory', 'r+'); // will need a handler
// Register a simple stream handler (see docs below) …
// ValueSerializer::registerResourceHandler('stream', $wrap, $restore);
$blob = ValueSerializer::serialize([$adder, $stream]);
$same = ValueSerializer::unserialize($blob);
Encode / Decode (base64)#
$payload = ['id' => 42, 'cb' => fn() => 'hi'];
$token = ValueSerializer::encode($payload); // base64 by default
$clone = ValueSerializer::decode($token);
echo ($clone['cb'])(); // "hi"
Signed payload mode (recommended for untrusted transport)#
ValueSerializer::setPayloadSigningKey($_ENV['INTERMIX_SIGNING_KEY']);
$token = ValueSerializer::encode(['id' => 7]); // signed internally
$same = ValueSerializer::decode($token); // signature verified
Security note#
If payloads can be modified by external/untrusted actors, enable
setPayloadSigningKey(...) before using decode()/unserialize().
Manual wrap / unwrap#
See wrap() / unwrap() example in the original docs – unchanged.
Registering a Resource Handler#
(Identical to previous version – shown here abbreviated)
ValueSerializer::registerResourceHandler(
'stream',
fn ($res) => /* …wrap… */ ,
fn ($data) => /* …restore… */
);