Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Serializable Closure Laravel Package

laravel/serializable-closure

Securely serialize and unserialize PHP closures with Laravel’s fork of opis/closure 3.x, updated for modern PHP without requiring FFI. Wrap closures in SerializableClosure, set a secret key for signing, serialize safely, then restore with getClosure().

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Core Use Case Alignment: The package directly addresses a critical gap in PHP/Laravel ecosystems—serializing closures, which are inherently non-serializable by default. This is particularly valuable for:
    • Queue jobs (e.g., Laravel queues, Horizon) where closures are passed as payloads.
    • Caching (e.g., Redis, Memcached) closures as callable logic.
    • Stateful middleware/filters where closures encapsulate logic.
    • Event listeners or service providers with dynamic closures.
  • Laravel-Native: Built and maintained by Laravel’s team, ensuring compatibility with Laravel’s internals (e.g., queues, caching layers, and event systems). Avoids reinventing the wheel for Laravel-specific use cases.
  • Extensibility: The package is designed to wrap closures in a serializable object (SerializableClosure), allowing for future extensions (e.g., encryption, signing, or custom serialization logic).

Integration Feasibility

  • Low Friction: Requires minimal changes—wrap closures in SerializableClosure before serialization (e.g., serialize(new SerializableClosure($closure))). No need to modify existing closure logic.
  • Backward Compatibility: Works with PHP 7.4+ and Laravel 8+. Supports modern PHP features (e.g., PHP 8.5’s constant expressions, attributes).
  • Dependency Graph: Lightweight (single Composer package) with no external dependencies beyond PHP’s core. No risk of version conflicts or bloated dependencies.
  • Laravel Ecosystem Synergy:
    • Queues: Native support for serializing closures in job payloads (e.g., Bus::chain).
    • Caching: Works seamlessly with Laravel’s cache drivers (e.g., Cache::put($key, $serializedClosure)).
    • Events: Enables serializing event listeners or closures in event payloads.

Technical Risk

Risk Area Assessment Mitigation
Security Closures must be signed to prevent tampering. The package provides setSecretKey() for signing, but misconfiguration (e.g., hardcoded keys) could expose vulnerabilities. Enforce secure key management (e.g., environment variables, Laravel’s config). Use sign: true explicitly in SerializableClosure.
Performance Overhead Serialization/deserialization adds CPU/memory overhead. Benchmarking shows ~10-20% overhead for complex closures (per opis/closure benchmarks). Profile critical paths (e.g., queue jobs). Cache serialized closures where possible. Avoid overusing for trivial logic.
Edge Cases Caveats in README (e.g., REPL environments, multiple closures on the same line) may break in edge cases. PHP 8.4+ virtual properties or attributes could introduce regressions. Test in staging with real-world closures (e.g., from migrations, middleware). Use SerializableClosure::setSecretKey() to debug deserialization failures.
Dependency on PHP Features Relies on PHP’s serialize()/unserialize(), which may behave unpredictably with custom objects or magic methods. PHP 8.5+ features (e.g., constant expressions) are supported but untested in all contexts. Validate with PHPStan/Psalm. Test on target PHP versions. Avoid closures with dynamic __invoke or magic methods.
Laravel Version Lock Officially supports Laravel 12/13 but may work with older versions. No guarantees for Laravel 11 or below. Pin to a stable minor version (e.g., ^2.0) in composer.json. Test against target Laravel version.

Key Questions for the Team

  1. Use Cases:
    • Where are closures currently serialized manually (e.g., base64, custom JSON)? How does this package improve reliability/security?
    • Are there performance-critical paths (e.g., high-throughput queues) where overhead is unacceptable?
  2. Security:
    • How will the secretKey be managed (e.g., environment variable, Laravel config)? Is signing enabled by default?
    • Are there sensitive closures (e.g., auth logic) that require additional protection (e.g., encryption)?
  3. Compatibility:
    • What PHP/Laravel versions are in use? Are there custom serialization handlers (e.g., for Eloquent models) that could conflict?
    • Are closures used in REPL environments (e.g., Tinker, Artisan commands)? If so, how will this be handled?
  4. Testing:
    • Are there existing tests for closure serialization? Can they be adapted to use this package?
    • Should integration tests cover edge cases (e.g., nested closures, closures with attributes)?
  5. Alternatives:
    • Has opis/closure been considered? Why was this Laravel fork preferred?
    • Are there other serialization strategies (e.g., JSON + Closure::fromCallable) that could complement this?

Integration Approach

Stack Fit

  • Laravel-Centric: Optimized for Laravel’s stack (queues, caching, events, service containers). Leverages Laravel’s configuration system (e.g., config('app.serializable_closure_secret')).
  • PHP Ecosystem: Works with any PHP 7.4+ application, but Laravel-specific features (e.g., queue jobs) unlock the most value.
  • Tooling Compatibility:
    • Queues: Integrates with Laravel Queues (e.g., Bus::chain), Horizon, and third-party queue systems (e.g., RabbitMQ, SQS).
    • Caching: Plays well with Laravel Cache (Redis, Memcached, database) and third-party caches (e.g., Predis).
    • Events: Enables serializing closures in event payloads or listeners.
    • Testing: Compatible with PHPUnit/Pest for testing serialized closures.

Migration Path

Current State Migration Strategy Risks
Manual Serialization (e.g., base64_encode(serialize($closure))) Replace with SerializableClosure::serialize($closure). Update deserialization to use unserialize($serialized)->getClosure(). Breaking changes if existing code relies on raw serialize() output.
Custom JSON/Closure Workarounds (e.g., ['class' => 'Closure', 'data' => ...]) Replace with SerializableClosure. Update serialization logic to emit SerializableClosure objects instead of raw closures. May require changes to cache/event systems if they expect specific payload formats.
No Closure Serialization Identify pain points (e.g., queues, caching) and introduce SerializableClosure incrementally. Start with non-critical paths (e.g., logging, analytics). Risk of missed use cases. Requires proactive discovery of closures needing serialization.
Third-Party Packages (e.g., opis/closure) Replace opis/closure with laravel/serializable-closure. Update imports and configuration (e.g., secret key). Potential API differences (e.g., method names, signing behavior).

Compatibility

  • Laravel Versions:
    • Officially supports Laravel 12/13. Tested against Laravel 11 in some PRs but not guaranteed.
    • Action: Pin to ^2.0 in composer.json and test against target Laravel version.
  • PHP Versions:
    • Supports PHP 7.4–8.5. PHP 8.5+ features (e.g., constant expressions) are supported but may need validation.
    • Action: Test on the minimum PHP version in use (e.g., PHP 8.1).
  • Dependencies:
    • No hard dependencies beyond PHP core. Soft dependencies (e.g., Pest, PHPUnit) for testing.
    • Action: Audit composer.json for conflicts (e.g., opis/closure).
  • Edge Cases:
    • Closures in REPL: Unsupported (per README). Avoid using in Tinker/Artisan commands.
    • Multiple Closures on Same Line: May fail to deserialize. Refactor code to place closures on separate lines.
    • Virtual Properties/PHP 8.4+: Fixed in v2.0+, but test with custom objects.

Sequencing

  1. Phase 1: Proof of Concept
    • Test SerializableClosure in a non-production environment with 2–3 critical use cases (e.g., a queue job, a cached closure).
    • Validate serialization/deserialization round-trips and performance.
  2. Phase 2: Incremental Rollout
    • Start with low-risk areas (e.g., logging, analytics closures).
    • Replace manual serialization
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai