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.
- 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.
- Automatic parameter binding — Opt into class-defined conversion of scalar bindings into typed objects, including in source-free compiled runtimes.
- 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 with native scoped inputs 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.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.
composer require infocyph/intermixOptional integrations:
composer require infocyph/cachelayer:^4.0
composer require infocyph/runwire:^2.1.1
composer require opis/closure:^4.5<?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')],
);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),
]),
);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);
}Named arguments match parameter names directly, preserving supplied zero, false,
and nullable null values. To convert an identifier such as ['logger' => 32]
into a typed Logger parameter, opt in with $builder->enableAutoBind() and
define a public static Logger::fromBoundValue(mixed $value): static method.
Conversion is disabled by default. See runtime invocation
for the contract, error handling, and scope ownership rules.
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.
$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 runtime factories, hooks or other fallback configuration;
use the configured builder's production() for those applications. Source-free
runtimes also support make() and invoke() with the artifact's frozen injection,
attribute, and auto-binding options. They do not reconstruct the original builder.
Declared input() entries compile natively with scoped lifetime. Supply them
through withinScope() seeds; missing inputs and undeclared seeds fail closed.
Inputs require an active scope and cannot be captured by singleton construction.
InterMix 11.2 uses compiled artifact ABI 3. Recompile older artifacts before upgrading. See compiled runtimes for trusted prevalidated loading and 11.2 release notes for migration details.
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.
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.
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.
Do not disclose suspected vulnerabilities in a public issue, discussion or pull request. Follow SECURITY.md and use GitHub private vulnerability reporting.
InterMix is protected by PHPForge, which provides automated tests, static and taint analysis, dependency auditing, architecture checks and release-readiness gates. Automated controls do not replace responsible disclosure or manual review.
MIT Licensed
Documentation • Security • Code of Conduct • Contributing
🗂️ Bug • Feature • Documentation • Question • CI failure
🔀 General • Bug fix • Feature • Refactor • Performance • Security & reliability • Documentation • Maintenance