Build a PHP QueryBuilder from scratch!


I recently completed one of the most challenging milestones of my framework: the ORM and QueryBuilder system.

It’s a complex component that required deep understanding of OOP, SQL abstraction, and design principles.

The Goal

I wanted to understand what truly happens behind the scenes when writing fluent database queries.

Instead of using Laravel or Symfony, I decided to build my own ORM from scratch — focusing on architecture, not shortcuts.




Architecture Overview

The Soft ORM system is inspired by modern framework technologies,

but built entirely from scratch.

Every Model represents a table, and the QueryBuilder dynamically generates and executes SQL statements.

Execution Flow

  1. User::find(1) → Extends the base Model
  2. Model.php → Creates the instance and forwards static calls to the QueryBuilder
  3. QueryBuilder.php → Builds the SQL query (SELECT * FROM …)
  4. Database.php → Singleton PDO that executes the query
  5. ResultSet → Handles model hydration



Design Patterns

Pattern Purpose
Active Record Each Model manages its table and CRUD operations.
Builder The QueryBuilder constructs SQL queries fluently.
Dependency Injection PDO is injected via container for separation of concerns.
Chain of Responsibility Methods like where() and join() return self for chaining.
Fail Fast Design Invalid Model structures throw ModelStructureException.

Writing an ORM from scratch forces a focus on architecture, abstraction, and class responsibility.

It reveals the value of separation between logic, data, and infrastructure layers.

The first unit tests for the QueryBuilder validate SQL generation and parameter binding.

They ensure the ORM behaves consistently before adding advanced features such as relationships and eager loading.

Try It Out

Repository:

GitHub – dev-iadicola/soft-php-mvc


bash
git clone https://github.com/dev-iadicola/soft-php-mvc.git
cd soft-php-mvc
composer install
php soft serve
Enter fullscreen mode

Exit fullscreen mode



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *