opis/closure
Serializable closures for PHP: safely capture and transport anonymous functions across processes or requests. Useful for caching, queues, sessions, and distributed jobs, with support for binding, scope, and restoring closures without manual refactoring.
Start by installing the package via Composer:
composer require opis/closure
The core API is minimal and intuitive: use Opis\Closure\serialize() and Opis\Closure\unserialize() as drop-in replacements for PHP’s native serialize() and unserialize(). For example:
use Opis\Closure\serialize, Opis\Closure\unserialize;
$closure = function($name) { return "Hello, {$name}!"; };
$serialized = serialize($closure);
$restored = unserialize($serialized);
echo $restored('World'); // Outputs: Hello, World!
Your first use case is likely storing a closure in a cache or queue payload—especially when working with Laravel queues, Redis, or Symfony’s Cache component—where native closures would otherwise fail serialization.
dispatch(new ProcessJob(serialize($closure)));
// Inside the job:
$fn = unserialize($this->serializedClosure);
$fn($payload);
$key = md5(serialize($closure) . serialize($args));
$result = $cache->getOrSet($key, fn() => $closure(...$args));
use() variables and this binding.Always prefer Opis\Closure\serialize() over native serialize() when closures are involved—no code changes needed beyond the import and wrapper call.
unserialize() can execute arbitrary code if given malicious input. Only untrusted user-provided serialized data in production. For safety, prefer signed payloads or whitelist sources (e.g., own queue jobs).Closure::bind()) are supported, but the bound object must be serializable. Avoid binding PDO connections or resources—they’ll break during serialization.unserialize() throws Opis\Closure\SerializationException, inspect the exception message—it usually reveals missing dependencies (e.g., use($x) referencing a non-serializable class). Run with Xdebug enabled to trace closure structure during serialization.Opis\Closure\Serializer::registerSerializer() if handling custom object types, though this is rarely needed.How can I help you explore Laravel packages today?