abmmhasan / intermix
A lightweight, high-performance PHP dependency injection and runtime utility toolkit with invocation, scoped services, compiled resolution, Closure serialization, Fence and fluent helpers.
Requires
- php: >=8.4
- psr/cache: ^3.0
- psr/container: ^2.0
Requires (Dev)
- infocyph/cachelayer: ^4.0
- infocyph/phpforge: dev-main@dev
- infocyph/runwire: ^2.1
- opis/closure: ^4.5
Suggests
- ext-mbstring: Recommended for development tools output formatting (Pest/Termwind)
- infocyph/cachelayer: Recommended PSR-6 cache implementation with memory, APCu, SQLite, Redis/Valkey, tiered and node-local adapters
- infocyph/runwire: Optional Runwire 2.1 request/task context propagation for InterMix scopes and CacheLayer forwarding
- opis/closure: Required only when using InterMix Closure serialization
Provides
None
Conflicts
None
Replaces
None
- dev-main
- 11.1
- 11.0
- 10.1.1
- 10.1
- 10.0.4
- 10.0.3
- 10.0.2
- 10.0.1
- 10.0
- 9.2
- 9.1.1
- 9.1
- 9.0
- 8.1
- 8.0
- 7.3.2
- 7.3.1
- 7.3
- 7.2.5
- 7.2.4
- 7.2.3
- 7.2.2
- 7.2.1
- 7.2
- 7.1.1
- 7.1
- 7.0
- 6.0
- 5.35.1
- 5.35
- 5.34.02
- 5.34.1
- 5.34
- 5.33.11
- 5.33.1
- 5.33
- 5.32.1
- 5.32
- 5.31.1
- 5.31
- 5.3.1
- 5.3
- 5.2.1
- 5.2
- 5.1
- 5.0.01
- 5.0
- 4.02
- 4.01.1
- 4.0
- 3.01.5
- 3.01.4
- 3.01.3
- 3.01.2
- 3.01.1
- 3.01
- 3.0
- 2.00.2
- 2.00.1
- 2.0
- 1.08.7
- 1.08.6
- 1.08.5
- 1.08.4
- 1.08.3
- 1.08.2
- 1.08.1
- 1.08
- 1.07.3
- 1.07.2
- 1.07.1
- 1.06.01
- 1.06
- 1.05.3
- 1.05.2
- 1.05.1
- 1.05
- 1.04
- 1.03
- 1.02
- 1.01.01
- 1.01.0
- 1.0.0
- dev-fix/runtime-gen
- dev-readme
This package is auto-updated.
Last update: 2026-10-04 10:47:10 UTC
README
InterMix is a PHP 8.4+ dependency-injection and runtime utility library focused on explicit configuration, immutable runtime wiring, scoped execution, compiled resolution, and low host overhead.
InterMix 11 separates configuration from execution:
- ContainerBuilder owns definitions and configuration.
- Container and ProductionContainer execute a finalized graph.
- RuntimeContainerInterface is the common runtime contract.
- Scoped work uses structured scope callbacks instead of manual enter/leave pairs.
- Optional Runwire and CacheLayer integration remains host-owned.
Key features
- Dependency injection — A PSR-11 runtime with explicit value, autowire, factory, alias, and host-input definitions.
- Invocation — Resolve services, construct fresh objects, invoke callables, inject attributes, and discover tagged services through one runtime contract.
- Scoped execution — Isolate request and job state, seed declared inputs, and propagate explicit scope contexts across structured Fiber or coroutine work.
- Compiled production runtime — Generate and validate immutable resolution artifacts while retaining narrow fallbacks for dynamic behavior.
- Definition caching — Warm eligible factory results through a caller-owned PSR-6 pool, including CacheLayer 4, with bounded and fail-open persistence.
- Runwire integration — Accept the host's active Runwire 2.1 runtime and request/task context, forward it to compatible capabilities such as CacheLayer, and leave worker and event-loop ownership with the host.
- Closure serialization — Serialize versioned Closure payloads with explicit unsigned and signed modes through the optional Opis integration.
- Fence — Enforce singleton-style construction rules where a class needs a single guarded instance.
- Remix and MacroMix — Add fluent conditionals, tap proxies, reusable traits, and dynamic object or class macros.
- Optional functional helpers — Load focused utilities such as
tap(),when(),pipe(),measure(), andretry()only when wanted.
Installation
composer require infocyph/intermix
Optional integrations:
composer require infocyph/cachelayer:^4.0 composer require infocyph/runwire:^2.1 composer require opis/closure:^4.5
Quick start
<?php declare(strict_types=1); use Infocyph\InterMix\DI\ContainerBuilder; use Infocyph\InterMix\DI\Support\LifetimeEnum; final class Clock {} final class RequestContext { public function __construct(public string $requestId) {} } final class Handler { public function __construct( public Clock $clock, public RequestContext $request, ) {} } $builder = ContainerBuilder::create('app') ->autowire(Clock::class, Clock::class) ->input(RequestContext::class) ->autowire( Handler::class, Handler::class, lifetime: LifetimeEnum::Scoped, tags: ['request-handler'], ); $runtime = $builder->build(); $result = $runtime->withinScope( 'request-123', static fn ($active) => $active->get(Handler::class), [RequestContext::class => new RequestContext('request-123')], );
Explicit definition kinds
Use one builder operation per intent:
$builder ->value('app.name', 'InterMix') ->autowire(Logger::class, JsonLogger::class) ->factory('token', static fn () => bin2hex(random_bytes(16))) ->alias(Psr\Log\LoggerInterface::class, Logger::class) ->input(RequestContext::class);
A value is always returned literally. A factory is always executed as a factory. Class construction is declared with autowire.
For compilation-safe construction recipes use FactoryDefinition:
use Infocyph\InterMix\DI\Support\FactoryDefinition; use Infocyph\InterMix\DI\Support\ServiceReference; $builder->factory( Mailer::class, FactoryDefinition::construct(Mailer::class, [ new ServiceReference(MailerConfig::class), ]), );
Runtime operations
The runtime contract is intentionally small:
$service = $runtime->get(Service::class); $fresh = $runtime->make(Job::class, ['name' => 'daily']); $result = $runtime->invoke([$service, 'handle'], ['payload' => $payload]); foreach ($runtime->tagged('listener') as $id => $listener) { $listener->handle($event); }
Scopes
Declare request/job supplied values before finalization, then seed them when a scope begins:
$builder ->input(RequestContext::class) ->autowire( RequestService::class, RequestService::class, lifetime: LifetimeEnum::Scoped, ); $runtime = $builder->build(); $response = $runtime->withinScope( 'request-42', static fn ($active) => $active->get(RequestService::class), [RequestContext::class => $context], );
For child work, capture the active ScopeContext and reattach it with withinScopeContext. The borrower attaches and detaches only; the owner closes the scope.
Compiled production runtime
$builder = ContainerBuilder::create('app') ->releaseIdentity('2026-10-01') ->autowire(Logger::class, JsonLogger::class) ->autowire(Mailer::class, Mailer::class); $report = $builder->compile(__DIR__ . '/var/intermix.php', strict: true); $runtime = $builder->production(__DIR__ . '/var/intermix.php');
The generated artifact is validated against the finalized graph, InterMix ABI, PHP runtime, environment identity, release identity, and fallback requirements before activation.
For a fully compiled deployment with no fallback requirements, cold SAPI bootstrap can load the artifact without rebuilding its configuration runtime:
$runtime = ContainerBuilder::loadProductionArtifact( path: __DIR__ . '/var/intermix.php', expectedGraphIdentity: $deployment['intermix_graph'], expectedEnvironment: 'production', );
Record compile()'s graph in immutable deployment metadata and pass that
expected identity at bootstrap. This path still validates the artifact digest,
build identity, ABI, PHP version, graph and environment. It rejects artifacts
that require inputs, runtime factories, hooks or other fallback configuration;
use the configured builder's production() for those applications. A standalone
runtime supports its compiled graph and has no dynamic configuration fallback.
Definition cache
Definition caching is explicit, PSR-6 based, and opt-in per eligible factory definition:
$builder ->definitionCache($pool, namespace: 'app', generation: '2026-10-01') ->factory('settings', SettingsFactory::definition()) ->cacheDefinition('settings'); $report = $builder->warmDefinitionCache();
Cache failures can remain fail-open when configured, but unsupported or over-budget values are never forced into external persistence.
Runwire integration
InterMix does not create or own a Runwire runtime. The host supplies its existing runtime/request/coroutine context through Infocyph\InterMix\Integration\Runwire\RunwireIntegration. See docs/integrations.rst.
Upgrade from 10.1
InterMix 11 intentionally removes mutable runtime configuration, manager proxies, process-global container lookup, descriptor-style invocation, and manual scope lifecycle APIs. See docs/upgrade-11.0.rst for the migration table.
Quality and performance
The release gates use PHPForge QA/analysis, PHP 8.4 and 8.5, stable/lowest dependency lanes, clean production install, Swoole/OpenSwoole scope-carrier checks, component regression measurements, and representative persistent-host acceptance.
License: MIT.