Getting started
In this guide we will create one class-based query and one builder-based query, then look at when each style makes sense.
1. Install the package
composer require phpgt/sqlbuilder
2. Create your first query class
Create a PHP class that extends SelectQuery:
use GT\SqlBuilder\Query\SelectQuery;
class StudentSelect extends SelectQuery {
public function select():array {
return [
"id",
"name",
"dateOfBirth",
];
}
public function from():array {
return [
"student",
];
}
}
Now render it:
echo new StudentSelect();
Output:
select
id,
name,
dateOfBirth
from
student
At this point there is no database connection involved. We have only built the SQL string.
3. Extend the query instead of copying it
Now imagine we need a second query for active students only. We can extend the first query:
class ActiveStudentSelect extends StudentSelect {
public function where():array {
return [
"deletedAt is null",
"status = 'active'",
];
}
}
That gives us reuse without string duplication.
4. Build the same kind of query inline
Sometimes a named class is too much ceremony for a tiny one-off query. In that case, use SelectBuilder:
use GT\SqlBuilder\SelectBuilder;
$query = new SelectBuilder();
$query->select(
"id",
"name",
"dateOfBirth",
)->from(
"student",
)->where(
"deletedAt is null",
"status = 'active'",
);
echo $query;
This produces the same shape of SQL, but the query stays close to the place where it is used.
5. Know when to choose which style
As a rule of thumb:
- use a query class when the query has a name in your domain.
- use a query class when other queries will extend it.
- use a builder when the query is stored as a variable in code, rather than file on disk.
If you are not sure, start with the query class. It scales better as the application grows.
6. Keep placeholders as placeholders
SqlBuilder will happily render parameter placeholders such as :id or ?, but it does not bind them itself.
class StudentByIdSelect extends StudentSelect {
public function where():array {
return [
":id",
];
}
}
This renders:
where
id = :id
That is often exactly what we want, because the database layer can bind the real value later.
[!TIP] If you are using
phpgt/database, this pairs naturally with named or positional parameter binding in the execution layer.
Now that we have seen the basic shape, move on to Writing query classes for the full class-based API.