Download the PHP package omega-mvc/serializable-closure without Composer

On this page you can find all versions of the php package omega-mvc/serializable-closure. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package serializable-closure

Omega Logo

Serializable Closure Package

Documentation | Changelog | Contributing | Code Of Conduct | License

PHPUnit PHPCS PHPStan Packagist Version

Omega - Serializable Closure

Overview

Omega - Serializable Closure is a powerful and flexible library designed to provide robust serialization capabilities for PHP closures. It addresses the inherent challenges of serializing closures, especially those with complex scopes and bound contexts, while also introducing enhanced security features through cryptographic signatures. This library is meticulously crafted to leverage modern PHP features and ensure the integrity and safety of your serializable closures.

Key Features

Requirements

Installation

To install Omega - Serializable Closure, you can use Composer:

Usage

Native Serialization (Unsigned)

For scenarios where cryptographic integrity is not a primary concern, you can use unsigned serialization.

Signed Serialization (HMAC)

For enhanced security, it's recommended to use signed serialization. This requires setting a secret key.

Security

The signed serialization mechanism utilizes HMAC (Hash-based Message Authentication Code) to ensure the integrity of serialized closures. When a secret key is provided using SerializableClosure::setSecretKey(), the library generates an HMAC signature of the serialized closure data. This signature is stored alongside the serialized data.

Upon deserialization, the library recalculates the HMAC signature using the same secret key and compares it with the provided signature. If the signatures do not match, an InvalidSignatureException is thrown, indicating that the serialized data may have been modified or corrupted since it was originally stored. This provides a crucial layer of defense against potential code injection or unauthorized modification of closures during transit or storage.

Fail-closed by design: loading signed data without the secret key throws MissingSecretKeyException instead of silently skipping verification. The key must be set before both serializing and unserializing signed closures.

Important:

Technical Architecture

Omega - Serializable Closure employs a sophisticated internal architecture to handle the complexities of closure serialization:

ClosureStream

This component registers a custom PHP stream wrapper (omega-serializable-closure://). This stream allows the library to represent the closure's source code as a stream, which is then included during deserialization. This method is an efficient way to reconstruct the closure from its string representation.

ReflectionClosure

This class extends PHP's native ReflectionFunction and provides advanced introspection capabilities for closures. It's instrumental in:

These components work in concert to provide a robust, secure, and flexible solution for serializing PHP closures, ensuring their integrity and faithful reconstruction.

Testing

The test suite runs on PHPUnit:

Tests live in tests/ (PSR-4 Tests\), with the suite configuration in phpunit.xml.dist. To run a single file or filter:

Stress Testing

The suite includes stress tests that execute serialization/deserialization cycles in a tight loop to detect memory leaks and resource accumulation. Stress tests are grouped under the stress group and can be targeted explicitly:

Iteration budget

The number of iterations per stress test is resolved at runtime by Tests\TestCase::stressIterations(). Because it reads the environment inside the test body — where the <env> variables declared in phpunit.xml.dist have already been applied — it behaves correctly whether the suite is launched by PHPUnit with the config file or standalone:

Condition Iterations
OMEGA_STRESS_ITERATIONS set (any positive int) value as-is
OMEGA_TEST_MODE=light 10
CI or GITHUB_ACTIONS set 100
Local development (default) 10 000

Stress tests are skipped automatically when the iteration budget is ≤ 1.

To override the automatic selection, export OMEGA_STRESS_ITERATIONS before running the suite (or set it via <env> in phpunit.xml.dist):

In CI environments the budget is reduced automatically (100 iterations) to keep pipeline times short. Locally the default is 10 000 iterations for thorough leak detection.

What is tested

Test Description
Native round-trips Repeated serialize()/unserialize() cycles through Native to ensure internal maps (bindings, instances, metadata) do not grow.
Signed round-trips Repeated Signed serialization with HMAC verification to catch resource accumulation in the signer path.
Complex closures Repeated deserialization of closures with a bound $this object and use variables, exercising the full __unserialize() decision tree under load.

Code Coverage

Coverage requires Xdebug (xdebug.mode=coverage) or PCOV:

The run generates an HTML report (lines, branches and paths) in cache/coverage/index.html. Plain composer test skips coverage on purpose: pass --no-coverage wherever a coverage driver is not available.

Known issue (xdebug ≤ 3.4.5): full-suite path-coverage runs may abort after every test has passed (double free or corruption, Segmentation fault) while Xdebug releases its path-tracking structures during shutdown. This is an upstream bug family (#2332, #1486), reproduced here on pristine sources — it is not caused by the test suite, and the printed summary remains valid. Rerun until green, split the run by suite file, or upgrade Xdebug (pecl upgrade xdebug, ≥ 3.4.7 recommended), which contains further crash fixes.

Reading the coverage report honestly

Line coverage sits at 100%; the other metrics do not, and that is by design rather than by neglect:

pathCoverage="true" stays enabled on purpose: reporting the ugly numbers honestly beats hiding them. Because of the run-to-run fluctuation described above, never quote a single-run branch/method figure as exact.

Static Analysis

Both must pass before committing; cache/ holds their result caches and is gitignored.

Known Limitations

A handful of PHPStan findings are tool/engine limitations rather than library bugs. They are suppressed inline with @phpstan-ignore-next-line (tagged with their error identifier) while we wait for PHPStan to gain first-class support for them; composer phpstan therefore exits 0 today.

Two are classic PHPStan false positives:

Error File Description
callable.nonCallable ReflectionClosureTest.php unserialize() returns mixed; a runtime instanceof guard protects the invocation.
function.inner ReflectionClosureTest.php Named function inside a closure body — valid PHP but unsupported by PHPStan (#165). Used as a tokenizer edge-case fixture.

By-reference mutation false positives

The former pest-plugin-phpstan rules reported five pest.expectation.impossible errors in NativeTest.php for assertions whose value had been mutated in place through ReflectionMethod::invokeArgs(): PHPStan evaluated each assertion against the pre-mutation static type instead of the runtime value. The Pest plugin rule no longer exists after the migration to PHPUnit, and core PHPStan (with PHPUnit's assertInstanceOf() / assertSame()) does not reproduce the false positive, so the five inline suppressions were removed. The assertions themselves remain the core behavioral checks for closure/self-reference resolution:

Setup type (static) Runtime value asserted What the test really verifies
Closure (inferred) Native mapByReference replaces a captured closure with a Native wrapper.
Closure (inferred) DateTimeImmutable Non-closure use values are left untouched by mapByReference.
SelfReference Closure mapPointers resolves a self-reference into the actual closure.
SelfReference Closure mapPointersValue resolves a SelfReference inside a nested array.
SelfReference Closure mapPointersValue resolves a SelfReference inside a stdClass.

PHP Limitations

These are not library bugs — they are inherent PHP constraints that affect every closure-serialization library (including Laravel's):

Limitation Explanation
By-reference closure parameters function (int &$val) cannot forward the reference through serialization. __invoke(mixed ...$args) uses variadic expansion, which copies values. Use use (&$var) instead for shared mutable state.
Anonymous classes Closures that capture anonymous class instances are not serializable. This mirrors PHP's own limitation — unserialize() cannot reconstruct unnamed classes.

Generating API Documentation with phpDocumentor

phpDocumentor is configured via phpdoc.xml.dist but the PHAR is not bundled. Install it separately and run:

Output lands in cache/apiDoc.

Troubleshooting

All composer scripts are prefixed with XDEBUG_MODE=off to avoid noisy xdebug output. When invoking the underlying tools directly, prefix them the same way:

Official Documentation

The official documentation for Omega is available here

Contributing

If you'd like to contribute to the OmegaMVC Serializable Closure package, please follow our contribution guidelines.

License

This project is open-source software licensed under the GNU General Public License v3.0.


All versions of serializable-closure with dependencies

PHP Build Version
Package Version
Requires php Version ^8.4
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package omega-mvc/serializable-closure contains the following files

Loading the files please wait ...