DatabaseQuery
An abstract base class for building SQL queries with parameterized bind values
Provides a fluent interface for composing query clauses that can be safely passed between methods and objects without knowledge of what other methods have added. Subclasses include Database for SELECT queries and Database for fulltext search queries.
You do not typically instantiate Database directly—use one of its concrete subclasses instead.
$query = new DatabaseQuerySelect();
$query->select("id, name")->from("pages")->where("status>?", 0)->orderby("name")->limit(25); All registered query methods (such as select, from, where, join, leftjoin, orderby, groupby, limit) are available as chainable methods via __call(). Each call appends to the existing clause, allowing multiple calls to build up complex queries incrementally.
$query = new DatabaseQuerySelect();
$query->select("id, name, status");
$query->from("pages");
$query->from("pages_sortfields"); // adds another table to FROM
$query->where("pages.parent_id=?", 10);
$query->where("pages.status>?", 0); // appends AND clause
$query->orderby("sortfield");
$query->limit(50); Named parameters
Pass bind values as an associative array in the second argument. Keys must start with : (the colon is auto-prepended if omitted):
$query->where("name=:name AND status=:status", [':name' => 'about', ':status' => 1]);Implied parameters (positional)
Use ? placeholders with a regular (numeric-keyed) array of values:
$query->where("name=? AND status=?", ['about', 1]);When there is only one ? placeholder, the value does not need to be wrapped in an array:
$query->where("parent_id=?", 10);Resetting a clause
Pass null to clear an existing clause 3.0.257:
$query->where(null); // clears all WHERE conditionsCombining queries
Use copyTo() to merge clauses from one query into another:
$queryA = new DatabaseQuerySelect();
$queryA->where("status>?", 0);
$queryA->orderby("name");
$queryB = new DatabaseQuerySelect();
$queryA->copyTo($queryB); // copies all clauses to $queryB
$queryA->copyBindValuesTo($queryB); // copies bind values too bindValue($key, $value, $type = null)
Bind a named parameter to a value. The key is auto-prefixed with : if not already present.
$query->bindValue(':name', 'hello');
$query->bindValue('status', 1); // colon auto-prependedThe optional $type argument accepts 'string', 'int', 'bool', 'null', or a PDO::PARAM_* constant.
bindValueGetKey($value, $type = null)
Bind a value and return a unique auto-generated key name in one step. Useful for building dynamic queries:
$key = $query->bindValueGetKey('hello'); // returns a unique key like ":s0X"
$query->where("name=$key");bindValues($bindValues = null)
Get or set multiple bind values at once. When called with no arguments, returns the current bind values array. When given an array, merges those values into the existing bind values (does not replace).
// Get all bind values
$values = $query->bindValues();
// Set multiple bind values
$query->bindValues([':name' => 'about', ':status' => 1]);getBindValues($options = array())
Get bind values with options. Supports the following options:
query(\PDOStatement|DatabaseQuery): Copy bind values to this query object. count(bool): Return count instead of array 3.0.157.inSQL(string): Only return bind values referenced in the given SQL string.
// Copy to a PDOStatement
$stmt = $database->prepare($query->getQuery());
$query->getBindValues(['query' => $stmt]);
// Count bind values
$count = $query->getBindValues(['count' => true]);copyBindValuesTo($query, $options = [])
Copy bind values from this query to another Database or PDOStatement. Returns the number of values copied.
$numCopied = $queryA->copyBindValuesTo($queryB);bindOption($optionName, $optionValue = null)
Get or set bind options. Options control how auto-generated bind keys are named:
prefix(string): Prefix for auto-generated keys (default:'pw').suffix(string): Suffix character (default:'X').global(bool): Make keys globally unique across all instances (default:false).
// Set global uniqueness for keys
$query->bindOption('global', true);
// Get all options
$allOptions = $query->bindOption(true);getQuery()
Returns the fully assembled SQL string. Also accessible via the $query->query or $query->sql property.
$sql = $query->getQuery();
// or
$sql = $query->query;getSQL($method = '')
Alias for getQuery(). If $method is specified, returns the SQL for only that clause:
echo $query->getSQL('where'); // just the WHERE clause SQL
echo $query->getSQL('orderby'); // just the ORDER BY clausegetQueryMethod($method)
Returns the generated SQL for a specific query method/clause:
$whereSQL = $query->getQueryMethod('where');getDebugQuery()
Returns the SQL query with bind parameters populated inline (for debugging only—not suitable for execution):
echo $query->getDebugQuery();
// SELECT id,name FROM `pages` WHERE status>0 ORDER BY nameprepare()
Prepares and returns a \PDOStatement with all bind values applied:
$stmt = $query->prepare();
$stmt->execute();
$results = $stmt->fetchAll(\PDO::FETCH_ASSOC);execute($options = [])
Prepares and executes the query in one step. Handles connection loss with automatic retry.
Options:
throw(bool): Throw exceptions on error (default:true).maxTries(int): Max retries on connection loss (default:3).returnQuery(bool): Return\PDOStatementif true,boolresult of execute if false (default:true).
// Execute and get PDOStatement
$stmt = $query->execute();
// Execute and get bool result
$ok = $query->execute(['returnQuery' => false]);| Property | Type | Description |
|---|---|---|
select | array | SELECT column expressions |
from | array | FROM table names |
join | array | JOIN clauses |
leftjoin | array | LEFT JOIN clauses |
where | array | WHERE/AND conditions |
orderby | array | ORDER BY expressions |
groupby | array | GROUP BY expressions |
limit | array | LIMIT values |
comment | string | Debug comment |
All clauses are available as fluent methods (inherited from Database):
select($columns, $params = [])
Add columns to the SELECT clause:
$query->select("id, name, status");
$query->select("count(*) AS total"); // appendfrom($table)
Add a table to the FROM clause. Tables are automatically backtick-quoted:
$query->from("pages"); // FROM `pages`
$query->from("pages_sortfields"); // adds second tablejoin($table, $params = [])
Add a JOIN clause:
$query->join("templates ON templates.id=pages.templates_id");leftjoin($table, $params = [])
Add a LEFT JOIN:
$query->leftjoin("field_title ON field_title.pages_id=pages.id");where($condition, $params = [])
Add a WHERE condition (first call) or AND condition (subsequent calls). Supports both named and implied bind parameters:
$query->where("status>?", 0);
$query->where("parent_id=:pid", [':pid' => 10]);orderby($value, $prepend = false)
Add ORDER BY. Can be called multiple times. Pass true as second argument to prepend rather than append:
$query->orderby("name"); // ORDER BY name
$query->orderby("created DESC"); // ORDER BY name, created DESC
$query->orderby("priority", true); // ORDER BY priority, name, created DESCgroupby($columns)
Add GROUP BY. Supports HAVING as a shortcut:
$query->groupby("parent_id");
// HAVING can be added as a "column" starting with HAVING:
$query->groupby("HAVING count>1");limit($limit)
Set the LIMIT clause:
$query->limit(25); // LIMIT 25
$query->limit("0, 25"); // LIMIT 0,25When $config->dbCache is false, SQL_NO_CACHE is prepended to the SELECT clause. This setting is static and shared across all instances.
Set a comment property to add a SQL comment (only in debug mode, as PDO misinterprets ? and :param patterns in comments):
$query->set('comment', 'Fetch homepage children');DatabaseextendsQuerySelectFulltext Wire, notDatabase. It decorates aQuery Databaserather than extending it.QuerySelect - The constant
maxQueryValueLength(500) limits search value length. - The class automatically handles stopwords, minimum word lengths, and MySQL fulltext index limitations.
- Word alternates (singular/plural, lemmas) are generated via
WireTextTools::getWordAlternates(). - Boolean mode uses
IN BOOLEAN MODEfor word-level matching and scoring. - Query expansion uses
WITH QUERY EXPANSIONfor related-word discovery. - The
matchStartEnd()method uses RLIKE regex with support for ICU (MySQL 8+) and HenrySpencer regex engines. - Score fields are uniquely named to avoid conflicts when multiple fulltext queries are combined.
- The
$fieldNameparameter ofmatch()can be an array for searching across multiple columns 3.0.169.
The primary method. Updates the decorated query with the appropriate MATCH...AGAINST WHERE clause and ORDER BY score. This is called by Fieldtype modules and PageFinder.
Parameters:
$tableName(string): Database table name.$fieldName(string): Column/field name (or array of names for multi-field search).$operator(string): Search operator (see table below).$value(string|int|array): Value to search for.
Supported operators
| Operator | Description | Method |
|---|---|---|
*= | Contains phrase (partial last word) | matchPhrase |
*+= | Contains phrase with query expansion | matchPhraseExpand |
**= | Contains match (non-boolean scored) | matchRegular |
**+= | Contains match with query expansion | matchRegular |
^= | Starts with | matchStartEnd |
$= | Ends with | matchStartEnd |
~= | Contains all full words | matchWords |
~+= | Contains all full words + expand | matchWords |
~*= | Contains all partial words | matchWords |
~~= | Contains all words live (partial last) | matchWords |
~\|= | Contains any full words | matchWords |
~\|*= | Contains any partial words | matchWords |
~\|+= | Contains any words + expand | matchWords |
~%= | Contains all words LIKE | matchLikeWords |
~\|%= | Contains any words LIKE | matchLikeWords |
%= | Contains phrase LIKE | matchLikePhrase |
%^= | Starts with LIKE | matchLikeStartEnd |
%$= | Ends with LIKE | matchLikeStartEnd |
#= | Boolean mode commands | matchCommands |
= | Equals | matchEquals |
!= | Not equals | matchEquals |
> / < / >= / <= | Comparison | matchEquals |
Negation
Prefix the operator with ! to negate the match (e.g., !*= for "does not contain phrase"):
$ft->match('field_body', 'data', '!~=', 'spam');allowOrder($allow = null)
Get or set whether ORDER BY score statements are added. When false, no ORDER BY is added (useful when the calling object will negate results):
$ft->allowOrder(false); // no ORDER BY scoreallowStopwords($allow = null)
Get or set whether fulltext searches fallback to LIKE for stopwords. Default is true:
$ft->allowStopwords(false); // ignore stopwords completelyforceLike($forceLike = null)
Force LIKE-based matching for operators that have LIKE equivalents (*=, ^=, $=, ~=, ~|=):
$ft->forceLike(true);getQuery()
Returns the Database object being decorated:
$query = $ft->getQuery();The intention behind these classes is to have a query that can safely be passed between methods and objects that add to it without knowledge of what other methods/objects have done to it. It also means being able to build a complex query without worrying about correct syntax placement.
This file is licensed under the MIT license
Below are Properties populated by Database Click any linked item for full usage details and examples. Hookable methods are indicated with the icon. In addition to those shown below, the In addition to the methods and properties above, DatabaseDatabase class also inherits all the methods and properties of: DatabaseCommon
Properties
Name Return Summary Database string Comments for query Database Field Field object that is referenced by this query. Database string Selector group (for OR-groups) if applicable. Database Database Parent query object, if applicable. Database Selector Selector object referenced by this query. Database Selectors Original selectors (all) that $selector is part of. Additional methods and properties
API reference based on ProcessWire core version 3.0.267