Skip to content

Getting Started

Muhammet Şafak edited this page May 24, 2026 · 1 revision

Getting Started

Five minutes from composer require to a working query.

Requirements

  • PHP ≥ 8.1
  • ext-pdo — only needed by your application when it actually executes the query. The builder itself never touches a connection.

Install

composer require initorm/query-builder

The package has zero runtime dependencies. The dev dependencies are PHPUnit, PHP_CodeSniffer and PHPStan.

Your first query

<?php

use InitORM\QueryBuilder\QueryBuilder;

require __DIR__ . '/vendor/autoload.php';

$qb = new QueryBuilder('mysql');

$qb->select('id', 'name')
   ->from('users')
   ->where('status', 1);

echo $qb->generateSelectQuery();

Output:

SELECT `id`, `name` FROM `users` WHERE `status` = 1

The constructor argument selects a dialect driver:

String Identifier quoting
'mysql' `
'pgsql' / 'postgres' / 'postgresql' "
'sqlite' `
null or any unknown string none (pass-through)

Pick the one that matches your target database. Switching drivers later is zero-cost — only the quoting character changes.

The factory

In dependency-injected setups, prefer the factory over new:

use InitORM\QueryBuilder\QueryBuilderFactory;

$factory = new QueryBuilderFactory();
$qb = $factory->createQueryBuilder('pgsql');

The factory is stateless; reuse one instance across the request.

Executing the SQL with PDO

The builder returns a SQL string and stores bound values in a separate parameter bag. Hand both to PDO:

$pdo = new PDO(
    'mysql:host=localhost;dbname=app;charset=utf8mb4',
    'app',
    'secret',
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION],
);

$qb->select('id', 'name', 'email')
   ->from('users')
   ->where('status', 1)
   ->andWhere('country', 'TR')
   ->orderBy('id', 'DESC')
   ->limit(20);

$sql        = $qb->generateSelectQuery();
$parameters = $qb->getParameter()->all();

$stmt = $pdo->prepare($sql);
$stmt->execute($parameters);

foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
    // …
}

getParameter()->all() returns the placeholder → value map keyed for PDO:

// [':country' => 'TR']

💡 Integer values (and a handful of other "safe" forms documented in Parameters) are inlined directly into the SQL rather than parameterized. Strings always go through the bag.

A first INSERT and UPDATE

// INSERT
$qb->resetStructure()
   ->from('users')
   ->set([
       'name'  => 'Muhammet',
       'email' => 'info@muhammetsafak.com.tr',
   ]);

echo $qb->generateInsertQuery();
// INSERT INTO `users` (`name`, `email`) VALUES (:name, :email);

// UPDATE
$qb->resetStructure()
   ->from('users')
   ->where('id', 5)
   ->set(['name' => 'Updated']);

echo $qb->generateUpdateQuery();
// UPDATE `users` SET `name` = :name WHERE `id` = 5

See INSERT UPDATE DELETE for the batch shapes and error paths.

Re-using a builder

Every public method that mutates the structure returns $this, so chaining is the usual style. When you want to start over without throwing away the builder, reset its structure:

$qb->resetStructure();          // blank slate
$qb->select('id')->from('post');

To snapshot and restore the structure:

$snapshot = $qb->exportQB();
// …
$qb->importQB($snapshot);

To spawn a sibling builder configured for the same dialect:

$other = $qb->newBuilder();     // fresh structure, same driver

Where to go next

  • SELECT Queries — every projection helper and the ordering / pagination knobs.
  • WHERE Clauses — the comparison matrix, value-shortcut, BETWEEN, IN, LIKE family, NULL checks, REGEXP, SOUNDEX, FIND_IN_SET.
  • JOIN Queries — the seven JOIN flavors plus the closure-based ON form.
  • Recipes — copy-pasteable patterns for pagination, soft-delete, dynamic filters, …
  • API Reference — quick lookup for every public method.

Coming from the v1 line? See Migration from v1 for the breaking changes.

Clone this wiki locally