Universal “Soldier” in PHP
Dependency Injection Without Pain (Symfony, Laravel, Drupal)
In the first article, we covered the controller as a universal entry point into any modern PHP framework.
Now it’s time for the next critical step — Dependency Injection (DI).
Many developers fear DI because:
- “There’s too much magic”
- “I don’t understand where objects come from”
- “In Drupal it’s a nightmare”
The good news is simple:
👉 Dependency Injection works the same way in all modern PHP frameworks.
Only the syntax and level of automation differ.
What Is Dependency Injection (in plain English)
Bad (tight coupling):
class OrderService {
public function __construct() {
$this->mailer = new Mailer();
}
}
Good (Dependency Injection):
class OrderService {
public function __construct(Mailer $mailer) {
$this->mailer = $mailer;
}
}
Core idea:
A class should not create its own dependencies — it should receive them from the outside.
Universal Rule #2
If you understand Dependency Injection in Symfony, you understand it in Laravel and Drupal.
Why?
Because all of them use a Service Container.
1. Symfony — the Reference Implementation
Symfony exposes DI clearly and explicitly. Nothing is hidden.
Service Example
// src/Service/Mailer.php
namespace App\Service;
class Mailer {
public function send(string $msg): void {
// send email
}
}
Injecting the Service into a Controller
use App\Service\Mailer;
use Symfony\Component\HttpFoundation\Response;
class HelloController
{
public function __construct(
private Mailer $mailer
) {}
public function index(): Response
{
$this->mailer->send('Hello');
return new Response('OK');
}
}
What’s happening here
- Symfony automatically registers the service
- Stores it in the container
- Injects it by type-hint (autowiring)
📌 Autowiring by type is the key concept.
2. Laravel — Same DI, More Sugar
Laravel may look different, but under the hood it’s the same idea.
Service
namespace App\Services;
class Mailer {
public function send(string $msg): void {}
}
Controller
use App\Services\Mailer;
class HelloController extends Controller
{
public function __construct(
private Mailer $mailer
) {}
public function index()
{
$this->mailer->send('Hello');
return 'OK';
}
}
Differences from Symfony
- Services don’t need explicit registration
- Laravel auto-discovers classes
- Fewer configuration files
📌 Laravel = Symfony DI with friendly defaults.
3. Drupal — DI with Heavy Armor
Drupal scares many developers, but once stripped down, it’s still Symfony DI.
Service in Drupal
// modules/custom/mymodule/src/Mailer.php
namespace Drupal\mymodule;
class Mailer {
public function send(string $msg): void {}
}
Service Registration (Required)
# mymodule.services.yml
services:
mymodule.mailer:
class: Drupal\mymodule\Mailer
Controller with DI
use Drupal\mymodule\Mailer;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\DependencyInjection\ContainerInterface;
class HelloController {
public function __construct(
protected Mailer $mailer
) {}
public static function create(ContainerInterface $container): self {
return new static(
$container->get('mymodule.mailer')
);
}
public function index(): Response {
$this->mailer->send('Hello');
return new Response('OK');
}
}
Why so verbose?
- Backward compatibility
- Explicit YAML configuration
- Strict control over services
📌 The concept is identical, only the ceremony differs.
Same Concept, Three Syntaxes
| Framework | Service Registration | Injection Method |
|---|---|---|
| Symfony | Auto / services.yaml | Constructor |
| Laravel | Auto | Constructor |
| Drupal | services.yml | create() + constructor |
The Most Common Mistake
❌ Don’t do this:
\Drupal::service('mailer');
app(Mailer::class);
❌ And don’t do this:
new Mailer();
✔️ Do this instead:
public function __construct(Mailer $mailer)
The Universal Pattern
Memorize this — it works everywhere:
class AnyClass {
public function __construct(
private Dependency $dependency
) {}
}
If a framework supports this — you’re home.
Conclusion
- DI is not a Symfony-only feature
- DI is not Laravel magic
- DI is not a Drupal punishment
It’s a core architectural principle, expressed differently across frameworks.
Master it once — and you stop being afraid of any PHP framework.
Comments