Query Builder w PHP - Bezpieczne i Czytelne Zapytania SQL
Czym jest Query Builder?
Query Builder to obiektowy interfejs do konstruowania zapytań SQL. Zamiast łączyć stringi, używasz metod zwracających $this
, co pozwala na łańcuchowe wywołania (Fluent Interface).
Dlaczego Query Builder zamiast surowego SQL?
- Bezpieczeństwo - automatyczne bindowanie parametrów eliminuje SQL Injection
- Czytelność - kod od lewej do prawej, jak czytamy naturalnie
- Komponowalność - łatwe budowanie dynamicznych zapytań
- IDE Support - autouzupełnianie i type hints
Podstawowe operacje CRUD
SELECT - pobieranie danych
<?php
// Proste SELECT
$users = $queryBuilder->select('users')
->where('active', '=', 1)
->get();
// SELECT z limitem i offsetem
$users = $queryBuilder->select('users')
->limit(10)
->offset(20)
->get();
// Pobieranie pojedynczego rekordu
$user = $queryBuilder->select('users')
->where('id', '=', 1)
->first();
INSERT - dodawanie rekordów
<?php
$queryBuilder->insert('users')
->values([
'name' => 'Jan Kowalski',
'email' => 'jan@example.com',
'password' => password_hash('secret', PASSWORD_DEFAULT)
])
->execute();
$userId = $queryBuilder->getInsertId();
UPDATE - aktualizacja danych
<?php
$queryBuilder->update('users')
->set(['name' => 'Anna Kowalska'])
->where('id', '=', 1)
->execute();
DELETE - usuwanie rekordów
<?php
$queryBuilder->delete('users')
->where('id', '=', 1)
->delete();
Zaawansowane WHERE - wzorzec Composite
System warunków WHERE wykorzystuje wzorzec Composite - każdy warunek implementuje ConditionContract
:
<?php
// Proste WHERE
$users = $queryBuilder->select('users')
->where('status', '=', 'active')
->where('role', '=', 'admin')
->get();
// WHERE status = 'active' AND role = 'admin'
// OR condition
$users = $queryBuilder->select('users')
->where('role', '=', 'admin')
->orWhere('role', '=', 'moderator')
->get();
// WHERE role = 'admin' OR role = 'moderator'
// LIKE pattern matching
$users = $queryBuilder->select('users')
->whereLike('email', '%@gmail.com')
->get();
// NULL checks
$users = $queryBuilder->select('users')
->whereNull('deleted_at')
->get();
// Grupowanie warunków z callback
$users = $queryBuilder->select('users')
->whereGroup(function($group) {
$group->where('role', '=', 'admin')
->orWhere('role', '=', 'moderator');
})
->where('active', '=', 1)
->get();
// WHERE (role = 'admin' OR role = 'moderator') AND active = 1
JOIN - łączenie tabel
Query Builder wspiera wszystkie typy JOIN używając wzorca Decorator:
<?php
// LEFT JOIN
$posts = $queryBuilder->select('posts')
->leftJoin(
table: 'users',
first: 'posts.user_id',
operator: '=',
second: 'users.id'
)
->where('posts.published', '=', 1)
->get();
// RIGHT JOIN
$users = $queryBuilder->select('users')
->rightJoin(
table: 'posts',
first: 'users.id',
operator: '=',
second: 'posts.user_id'
)
->whereNotNull('users.email')
->get();
// INNER JOIN
$orders = $queryBuilder->select('orders')
->innerJoin(
table: 'customers',
first: 'orders.customer_id',
operator: '=',
second: 'customers.id'
)
->get();
Bezpieczeństwo - Prepared Statements
Wszystkie wartości są automatycznie bindowane jako parametry PDO. Query Builder NIE łączy stringów, co eliminuje SQL Injection:
<?php
// Bezpieczne - wartości są bindowane
$email = $_POST['email']; // może zawierać "'; DROP TABLE users--"
$user = $queryBuilder->select('users')
->where('email', '=', $email)
->first();
// Generuje: SELECT * FROM users WHERE email = ?
// Parametry: [$email]
// PDO automatycznie escapuje wartości
Wzorce projektowe w Query Builder
- Builder Pattern - stopniowe budowanie zapytania
- Fluent Interface - metody zwracają $this
- Facade Pattern - QueryBuilder jako fasada dla InsertQueryBuilder, SelectQueryBuilder, etc.
- Decorator Pattern - JoinDecorator, LimitDecorator
- Composite Pattern - system warunków WHERE
🎓 Zbuduj Query Builder od podstaw!
W kursie PHP 8.4 implementujesz kompletny Query Builder z obsługą JOIN, WHERE, LIMIT oraz wzorcami Composite i Decorator. Pełna ochrona przed SQL Injection.