如何在PHP-DI 6的定义中正确使用autowire()、create()和get()?
Hey there! Let's break down how to use autowire(), create(), and get() in PHP-DI 6 with your exact service setup—this should clear up their similarities and when to pick each one.
First, a quick recap of your classes to keep us aligned:
FooServiceInterface&BarServiceInterface: The core interfacesFooAService/FooBService: ImplementFooServiceInterface, both depend onBarServiceInterfaceBarService: ImplementsBarServiceInterface, no dependencies of its own
autowire(): The "set it and forget it" auto-assembly This is the go-to function for most cases—it lets PHP-DI automatically resolve constructor dependencies using type hints. You don't have to manually pass dependencies; PHP-DI handles the heavy lifting.
Example with your services:
use DI\ContainerBuilder; use DI\DI; $builder = new ContainerBuilder(); $builder->addDefinitions([ // Bind the Bar interface to its implementation, auto-wire the instance BarServiceInterface::class => DI\autowire(BarService::class), // Bind Foo interface to FooAService—PHP-DI will automatically inject BarServiceInterface FooServiceInterface::class => DI\autowire(FooAService::class), // If you need a separate binding for FooBService (e.g., for a different scenario) 'FooBService' => DI\autowire(FooBService::class), ]); $container = $builder->build(); // When you fetch FooServiceInterface, PHP-DI creates BarService and injects it into FooAService automatically $fooService = $container->get(FooServiceInterface::class);
When to use it: Any time your services follow standard constructor injection (type-hinted dependencies) and you don't need custom logic for instance creation. It keeps your definitions clean and minimal.
create(): Manual control over instance creation Use create() when you want explicit control over constructor parameters—either to override auto-wired dependencies, pass non-container-managed values, or fine-tune how the instance is built.
Example with your services:
$builder->addDefinitions([ // For BarService, this acts the same as autowire() since there are no dependencies BarServiceInterface::class => DI\create(BarService::class), // Explicitly define the constructor parameter for FooAService FooServiceInterface::class => DI\create(FooAService::class) ->constructor(DI\get(BarServiceInterface::class)), // Manually reference the Bar service from the container // Hypothetical: If FooAService had an extra custom parameter (e.g., $apiKey) // FooServiceInterface::class => DI\create(FooAService::class) // ->constructor(DI\get(BarServiceInterface::class), "my-secret-api-key"), ]);
When to use it: When you need to customize the instance creation process—like injecting hardcoded values, using a specific instance of a dependency instead of the default, or when auto-wiring isn't sufficient (e.g., ambiguous dependencies).
get(): Reuse existing container definitions get() isn't for creating new instances—it's for referencing services that are already defined in the container. Think of it as a way to "link" to existing definitions instead of redefining them.
Example with your services:
$builder->addDefinitions([ // First, register BarService with autowire BarServiceInterface::class => DI\autowire(BarService::class), // Register FooAService as a standalone service FooAService::class => DI\autowire(), // PHP-DI auto-injects BarServiceInterface here // Now bind FooServiceInterface to the existing FooAService definition using get() FooServiceInterface::class => DI\get(FooAService::class), // You can also use get() inside create() to reference dependencies FooBService::class => DI\create() ->constructor(DI\get(BarServiceInterface::class)), ]);
When to use it: When you want to reuse an existing service definition (e.g., binding an interface to a service you already registered), or when you need to reference a service within another definition (like in factory functions or constructor parameters).
Quick Cheat Sheet
autowire(): Auto-resolve dependencies, minimal setup, use for most cases.create(): Manual constructor control, use for custom instance creation.get(): Reference existing services, use for reusing definitions.
内容的提问来源于stack exchange,提问作者automatix

