Understanding SOLID Principles in Laravel (with Simple Examples)

By May 6, 2025Laravel, OOP, PHP

The SOLID principles are five design principles that help developers write clean, maintainable, and scalable code. They were introduced by Robert C. Martin (Uncle Bob), and they form the backbone of good software architecture.

Let’s break them down with easy-to-understand definitions and Laravel examples.

What are SOLID Principles?
  • πŸ…’ – Single Responsibility Principle (SRP)
  • πŸ…ž – Open/Closed Principle (OCP)
  • πŸ…› – Liskov Substitution Principle (LSP)
  • πŸ…˜ – Interface Segregation Principle (ISP)
  • πŸ…“ – Dependency Inversion Principle (DIP)

Let’s break them down with Laravel examples.

1️⃣ Single Responsibility Principle (SRP)

“A class should have only one reason to change.”

❌ Violation Example

A UserController handling authentication, registration, and profile updates:

class UserController extends Controller {
    public function register(Request $request) { /* ... */ }
    public function login(Request $request) { /* ... */ }
    public function updateProfile(Request $request) { /* ... */ }
    public function deleteAccount(Request $request) { /* ... */ }
}

Problem:

  • If registration logic changes, we risk breaking login/profile updates.
  • Harder to test and maintain.
βœ… Solution (SRP in Laravel)

Split into dedicated classes:

class RegistrationController { public function register() { /* ... */ } }
class LoginController { public function login() { /* ... */ } }
class ProfileController { public function update() { /* ... */ } }

Benefits:

  • βœ” Easier to modify one feature without affecting others.
  • βœ” Better testability.
πŸ“Œ Real-Life Scenario
  • Before: A monolithic OrderController handling payments, shipping, and notifications.
  • After: Separate controllers for PaymentService, ShippingService, and NotificationService.

2️⃣ Open/Closed Principle (OCP)

“Software entities should be open for extension but closed for modification.”

❌ Violation Example

A PaymentProcessor with hardcoded payment methods:

class PaymentProcessor {
    public function pay($method) {
        if ($method == 'credit_card') { /* ... */ }
        elseif ($method == 'paypal') { /* ... */ }
    }
}

Problem:

  • Adding a new payment method (e.g., Stripe) requires modifying the class.
βœ… Solution (OCP in Laravel)

Use interfaces and dependency injection:

interface PaymentMethod { public function pay(); }

class CreditCardPayment implements PaymentMethod { /* ... */ }
class PayPalPayment implements PaymentMethod { /* ... */ }

class PaymentProcessor {
    public function pay(PaymentMethod $method) {
        $method->pay();
    }
}

Benefits:

  • βœ” New payment methods can be added without changing PaymentProcessor.
πŸ“Œ Real-Life Scenario
  • Before: Hardcoded logic for SMSNotification and EmailNotification.
  • After: Extend with SlackNotification without touching existing code.

3️⃣ Liskov Substitution Principle (LSP)

“Subclasses should be substitutable for their parent classes.”

❌ Violation Example

A Bird class with a fly() method, but Penguin can’t fly:

class Bird { public function fly() { /* ... */ } }
class Penguin extends Bird { /* Can't fly! */ }

Problem:

  • Penguin breaks the parent class’s contract.
βœ… Solution (LSP in Laravel)

Use interfaces to define behaviors:

interface Flyable { public function fly(); }
class Sparrow implements Flyable { /* ... */ }
class Penguin { /* No fly() method */ }

Benefits:

  • βœ” Prevents unexpected behavior in child classes.
πŸ“Œ Real-Life Scenario
  • Before: A FileStorage class forcing all subclasses to implement delete().
  • After: ReadOnlyStorage doesn’t need delete().

4️⃣ Interface Segregation Principle (ISP)

“Clients shouldn’t depend on interfaces they don’t use.”

❌ Violation Example

A bloated Worker interface:

interface Worker {
    public function work();
    public function eat();
    public function sleep();
}

class HumanWorker implements Worker { /* ... */ }
class RobotWorker implements Worker { /* Robots don't eat/sleep! */ }

Problem:

  • RobotWorker is forced to implement unnecessary methods.
βœ… Solution (ISP in Laravel)

Split into smaller interfaces:

interface Workable { public function work(); }
interface Eatable { public function eat(); }

class HumanWorker implements Workable, Eatable { /* ... */ }
class RobotWorker implements Workable { /* ... */ }

Benefits:

  • βœ” Cleaner, more focused classes.
πŸ“Œ Real-Life Scenario
  • Before: A NotificationService forcing SMS/Email/Slack in one interface.
  • After: Separate SMSNotifiable, EmailNotifiable interfaces.

5️⃣ Dependency Inversion Principle (DIP)

“Depend on abstractions, not concretions.”

❌ Violation Example

A OrderController tightly coupled to StripePayment:

class OrderController {
    public function pay() {
        $payment = new StripePayment();
        $payment->process();
    }
}

Problem:

  • Switching to PayPal requires rewriting the controller.
βœ… Solution (DIP in Laravel)

Use dependency injection:

interface PaymentGateway { public function process(); }

class StripePayment implements PaymentGateway { /* ... */ }
class PayPalPayment implements PaymentGateway { /* ... */ }

class OrderController {
    public function pay(PaymentGateway $payment) {
        $payment->process();
    }
}

Benefits:

  • βœ” Easily swap payment providers.
πŸ“Œ Real-Life Scenario
  • Before: Hardcoded MySQLDatabase dependency.
  • After: Switch to PostgreSQLDatabase without code changes.

πŸš€ Why SOLID Matters in Laravel?

  1. Maintainability: Easier to update code without breaking things.
  2. Testability: Isolated components = better unit tests.
  3. Scalability: New features can be added cleanly.
πŸ’‘ Pro Tip

Laravel’s Service Container and Dependency Injection naturally encourage SOLID principles.

πŸ“Œ Key Takeaways

Principle Laravel Example Real-World Benefit
SRP Split controllers/services Easier debugging
OCP Payment gateways Extend without modifying
LSP Interface inheritance Safe subclassing
ISP Notification channels No unused methods
DIP Dependency injection Swap implementations easily

πŸ”— Next Steps: Try refactoring a Laravel project using SOLID principles!

πŸ’¬ Your Turn!

Which SOLID principle do you find most useful in Laravel? Let’s discuss in the comments! πŸ‘‡

Nikhil Patel

Nikhil Patel

Hello Folks, I am PHP, laravel Developer having 8+ years of experience. I live in India and I like to write tips & tutorials so it can be helpful for IT folks. it will help to get a better solution for their projects. I am also a fan of Jquery, Vue JS, ReactJS, and bootstrap from the primitive stage.

Leave a Reply