Quick-Start#
InterMix works out-of-the-box – a single dependency via Composer and you’re up and running. This page merges the former Getting Started notes so you have one concise reference.
Create (or retrieve) a container#
A container is identified by an alias. Each alias is an isolated registry of services.
use Infocyph\InterMix\DI\Container;
use function Infocyph\InterMix\container;
require_once __DIR__ . '/vendor/infocyph/intermix/src/functions.php';
$c1 = container(); // default alias: intermix.default
$c2 = Container::instance('cli'); // a second, independent container
// identical:
$c3 = Container::instance('cli');
Keep aliases short and memorable – tests often use a random alias to isolate state.
For production/runtime stability, prefer explicit aliases instead of relying on the
default intermix.default alias.
Configure behaviour (optional)#
$c1->options()->setOptions(
injection: true, // reflection autowiring engine
methodAttributes: true, // honour #[Infuse] on parameters
propertyAttributes: true, // honour #[Infuse] on properties
defaultMethod: 'handle' // fallback method name
);
Defaults
injection = true
methodAttributes = false
propertyAttributes = false
lazyLoading = true
Register something#
Bind an ID to a value / factory#
$c1->definitions()
->bind('answer', 42)
->bind('now', fn () => new DateTimeImmutable());
Register a class with constructor parameters#
$c1->registration()->registerClass(PDO::class, [
'mysql:host=localhost;dbname=test', // DSN
'root', // user
'secret', // password
]);
Import a service provider#
Use a provider when you want one class to own all wiring for a feature/module. This keeps bootstrap files clean and lets you reuse the same registration set across CLI, HTTP, and tests.
use Infocyph\InterMix\DI\Container;
use Infocyph\InterMix\DI\Support\ServiceProviderInterface;
interface MailerInterface { public function send(string $to, string $text): void; }
final class Mailer implements MailerInterface
{
public function send(string $to, string $text): void
{
// send email...
}
}
final class MailProvider implements ServiceProviderInterface
{
public function register(Container $container): void
{
$container->definitions()->bind(MailerInterface::class, Mailer::class);
}
}
// import by class name (or pass new MailProvider())
$c1->registration()->import(MailProvider::class);
$mailer = $c1->get(MailerInterface::class);
$mailer->send('[email protected]', 'InterMix is running');
Resolve#
echo $c1->get('answer'); // 42
echo $c1->get('now')->format('c'); // 2025-06-18T12:34:56+00:00
Autowire a class (constructor injection):
class Greeter
{
public function __construct(DateTimeImmutable $clock) { $this->clock = $clock; }
public function hello(string $name): string
{
return 'Hi '.$name.' @ '.$this->clock->format('c');
}
}
echo $c1->get(Greeter::class)->hello('Bob');
A taste of attributes#
use Infocyph\InterMix\DI\Attribute\Infuse;
class Mailer
{
#[Infuse] private LoggerInterface $logger;
public function __construct(#[Infuse('cfg.smtp')] string $dsn = 'smtp://localhost') {}
}
$c1->definitions()
->bind(LoggerInterface::class, DummyLogger::class)
->bind('cfg.smtp', 'smtp://mail.prod');
$mailer = $c1->get(Mailer::class); // property + parameter injected
Environment swap (prod vs. local)#
interface PaymentGateway { public function pay(int $amount): string; }
class StripeGateway implements PaymentGateway { /* … */ }
class PaypalGateway implements PaymentGateway { /* … */ }
$c1->options()
->bindInterfaceForEnv('prod', PaymentGateway::class, StripeGateway::class)
->bindInterfaceForEnv('local', PaymentGateway::class, PaypalGateway::class)
->setEnvironment('prod');
$gw = $c1->get(PaymentGateway::class); // StripeGateway in prod
Lock & ship#
After bootstrap you may lock the container to block any further accidental modifications:
$c1->lock();
Happy mixing — your clay is ready!