When building PHP applications, understanding coupling is crucial for maintainable and flexible code. Let’s break it down.
1️⃣ Tightly Coupled Classes
A class is tightly coupled when it creates or knows about its dependencies directly. Any change in dependencies requires editing the class itself.
Example:
class PetrolEngine {
public function start() {
return "Petrol engine started";
}
}
class DieselEngine {
public function start() {
return "Diesel engine started";
}
}
class Car {
private $engine;
public function __construct($type) {
if ($type == 'petrol') {
$this->engine = new PetrolEngine();
} else {
$this->engine = new DieselEngine();
}
}
public function startCar() {
echo $this->engine->start();
}
}
$car = new Car('petrol');
$car->startCar();
Problem:
If you later introduce ElectricEngine, you must edit the Car class to handle it. This is tightly coupled.
2️⃣ Loosely Coupled Classes (Dependency Injection)
A class is loosely coupled when it doesn’t create its dependencies. Instead, dependencies are injected from outside. This makes code flexible and easier to maintain.
Example:
interface Engine {
public function start();
}
class PetrolEngine implements Engine {
public function start() {
return "Petrol engine started";
}
}
class DieselEngine implements Engine {
public function start() {
return "Diesel engine started";
}
}
class Car {
private $engine;
// Dependency is injected
public function __construct(Engine $engine) {
$this->engine = $engine;
}
public function startCar() {
echo $this->engine->start();
}
}
// Injecting dependencies from outside
$petrolCar = new Car(new PetrolEngine());
$petrolCar->startCar();
$dieselCar = new Car(new DieselEngine());
$dieselCar->startCar();
Benefits:
Cardoesn’t care about which engine it gets.- Adding
ElectricEnginedoesn’t require editingCar. - Code is flexible, testable, and loosely coupled ✅
✅ Key Takeaways
- Tightly Coupled: Class creates its dependencies → harder to maintain.
- Loosely Coupled: Class receives dependencies → flexible and testable.
- Dependency Injection (DI): Main technique to achieve loose coupling.
See if manual way to build DI and service container fails, just use package https://packagist.org/packages/php-di/php-di and you will be good to go with just 2 lines of code!
// inplace of manual let's use library php-id
require 'vendor/autoload.php';
$container = new DI\Container();
$container->get(Car::class);
