What are Factories in PHP and how to use them
When working with object-oriented programming in PHP, sooner or later you’ll need to create objects in a more flexible, controlled, and scalable way. This is where Factories come in — a very useful design pattern that helps you encapsulate object creation logic.
What Is a Factory?
A Factory is a creational design pattern that provides a way to create objects without having to specify the exact class of the object being created. Instead of using newdirectly everywhere, you centralize the object creation logic in a dedicated class or function.
This is useful when:
- You want to decouple your code from specific classes.
- The object creation logic is complex.
- You need to create different types of objects depending on certain parameters.
Basic Factory example
Let’s say we have a Vehicleinterface and two classes that implement it: Carand Motorcycle.
<?php
interface Vehicle {
public function move(): void;
}
class Car implements Vehicle {
public function move(): void {
echo "The car is moving";
}
}
class Motorcycle implements Vehicle {
public function move(): void {
echo "The motorcycle is moving";
}
}
Now, we create a factory that takes care of creating the correct vehicle type based on a parameter:
<?php
class VehicleFactory {
public function createVehicle(string $type): Vehicle {
if ( $type === 'car' ) {
return new Car();
}
if ( $type === 'motorcycle' ) {
return new Motorcycle();
}
throw new InvalidArgumentException("Invalid vehicle type: $type");
}
}
Using the factory.
<?php
$vehicleFactory = new VehicleFactory();
$myCar = $vehicleFactory->createVehicle('car');
$myCar->move(); // The car is moving 🚗
$myMoto = $vehicleFactory->createVehicle('motorcycle');
$myMoto->move(); // The motorcycle is moving 🏍️
Benefits of using a Factory
- Decoupling: The code that needs an object doesn’t have to know how it’s constructed.
- Reusability: If you need to change the creation logic, you do it in one place.
- Flexibility: You can return different subclasses or dynamically configured instances.
Static Factory
You can also implement the pattern using a static method:
<?php
class VehicleFactory {
public static function create(string $type): Vehicle {
return match($type) {
'car' => new Car(),
'motorcycle' => new Motorcycle(),
default => throw new InvalidArgumentException("Unsupported type: $type"),
};
}
}
// Usage
$vehicle = VehicleFactory::create('car');
$vehicle->move();
More realistic example: Factory with configuration
In more complex systems, object creation might depend on various parameters or even dependency injection. Let’s see an example:
<?php
class DatabaseConnection {
protected string $host;
protected string $username;
protected string $password;
public function __construct(string $host, string $username, string $password) {
$this->host = $host;
$this->username = $username;
$this->password = $password;
}
public function connect(): void {
echo "Connecting to $this->host as $this->username\n";
}
}
class DatabaseFactory {
public function createFromEnv(): DatabaseConnection {
return new DatabaseConnection(
getenv('DB_HOST'),
getenv('DB_USER'),
getenv('DB_PASS')
);
}
}
// Usage
$dbFactory = new DatabaseFactory();
$dbConnection = $dbFactory->createFromEnv();
$dbConnection->connect();
The Factory pattern is a powerful tool for creating objects in PHP in a controlled and flexible way. It’s especially helpful in medium to large applications where centralizing instantiation logic helps you keep your code clean, decoupled, and easier to maintain.




