ActiveQuery represents a DB query associated with an Active Record class.
An ActiveQuery can be a normal query or be used in a relational context.
ActiveQuery instances are usually created by yii\db\ActiveRecord::find() and yii\db\ActiveRecord::findBySql(). Relational queries are created by yii\db\ActiveRecord::hasOne() and yii\db\ActiveRecord::hasMany().
Normal Query ¶ActiveQuery mainly provides the following methods to retrieve the query results:
Because ActiveQuery extends from yii\db\Query, one can use query methods, such as where(), orderBy() to customize the query options.
ActiveQuery also provides the following additional query options:
These options can be configured using methods of the same name. For example:
$customers = Customer::find()->with('orders')->asArray()->all();
Relational query ¶
In relational context ActiveQuery represents a relation between two Active Record classes.
Relational ActiveQuery instances are usually created by calling yii\db\ActiveRecord::hasOne() and yii\db\ActiveRecord::hasMany(). An Active Record class declares a relation by defining a getter method which calls one of the above methods and returns the created ActiveQuery object.
A relation is specified by $link which represents the association between columns of different tables; and the multiplicity of the relation is indicated by $multiple.
If a relation involves a junction table, it may be specified by via() or viaTable() method. These methods may only be called in a relational context. Same is true for inverseOf(), which marks a relation as inverse of another relation and onCondition() which adds a condition that is to be added to relational query join condition.
Defined in: yii\base\Component::__call()
Calls the named method which is not a class method.
This method will check if any attached behavior has the named method and will execute it if available.
Do not call this method directly as it is a PHP magic method that will be implicitly called when an unknown method is being invoked.
public function __call($name, $params)
{
$this->ensureBehaviors();
foreach ($this->_behaviors as $object) {
if ($object->hasMethod($name)) {
return call_user_func_array([$object, $name], $params);
}
}
throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
}
public function __clone()
{
parent::__clone();
if (is_object($this->via)) {
$this->via = clone $this->via;
} elseif (is_array($this->via)) {
$this->via = [$this->via[0], clone $this->via[1], $this->via[2]];
}
}
Constructor.
public void __construct ( $modelClass, $config = [] ) $modelClass stringThe model class associated with this query
$config arrayConfigurations to be applied to the newly created query object
public function __construct($modelClass, $config = [])
{
$this->modelClass = $modelClass;
parent::__construct($config);
}
Defined in: yii\base\Component::__get()
Returns the value of a component property.
This method will check in the following order and act accordingly:
Do not call this method directly as it is a PHP magic method that will be implicitly called when executing $value = $component->property;
.
See also __set().
public function __get($name)
{
$getter = 'get' . $name;
if (method_exists($this, $getter)) {
return $this->$getter();
}
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canGetProperty($name)) {
return $behavior->$name;
}
}
if (method_exists($this, 'set' . $name)) {
throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
}
throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
}
Defined in: yii\base\Component::__isset()
Checks if a property is set, i.e. defined and not null.
This method will check in the following order and act accordingly:
false
for non existing propertiesDo not call this method directly as it is a PHP magic method that will be implicitly called when executing isset($component->property)
.
See also https://www.php.net/manual/en/function.isset.php.
public function __isset($name)
{
$getter = 'get' . $name;
if (method_exists($this, $getter)) {
return $this->$getter() !== null;
}
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canGetProperty($name)) {
return $behavior->$name !== null;
}
}
return false;
}
Defined in: yii\base\Component::__set()
Sets the value of a component property.
This method will check in the following order and act accordingly:
Do not call this method directly as it is a PHP magic method that will be implicitly called when executing $component->property = $value;
.
See also __get().
public function __set($name, $value)
{
$setter = 'set' . $name;
if (method_exists($this, $setter)) {
$this->$setter($value);
return;
} elseif (strncmp($name, 'on ', 3) === 0) {
$this->on(trim(substr($name, 3)), $value);
return;
} elseif (strncmp($name, 'as ', 3) === 0) {
$name = trim(substr($name, 3));
if ($value instanceof Behavior) {
$this->attachBehavior($name, $value);
} elseif ($value instanceof \Closure) {
$this->attachBehavior($name, call_user_func($value));
} elseif (isset($value['__class']) && is_subclass_of($value['__class'], Behavior::class)) {
$this->attachBehavior($name, Yii::createObject($value));
} elseif (!isset($value['__class']) && isset($value['class']) && is_subclass_of($value['class'], Behavior::class)) {
$this->attachBehavior($name, Yii::createObject($value));
} elseif (is_string($value) && is_subclass_of($value, Behavior::class, true)) {
$this->attachBehavior($name, Yii::createObject($value));
} else {
throw new InvalidConfigException('Class is not of type ' . Behavior::class . ' or its subclasses');
}
return;
}
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canSetProperty($name)) {
$behavior->$name = $value;
return;
}
}
if (method_exists($this, 'get' . $name)) {
throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
}
throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
}
public function __toString()
{
return serialize($this);
}
Defined in: yii\base\Component::__unset()
Sets a component property to be null.
This method will check in the following order and act accordingly:
Do not call this method directly as it is a PHP magic method that will be implicitly called when executing unset($component->property)
.
See also https://www.php.net/manual/en/function.unset.php.
public function __unset($name)
{
$setter = 'set' . $name;
if (method_exists($this, $setter)) {
$this->$setter(null);
return;
}
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canSetProperty($name)) {
$behavior->$name = null;
return;
}
}
throw new InvalidCallException('Unsetting an unknown or read-only property: ' . get_class($this) . '::' . $name);
}
public $this addGroupBy ( $columns ) $columns string|array|yii\db\ExpressionInterface
Additional columns to be grouped by. Columns can be specified in either a string (e.g. "id, name") or an array (e.g. ['id', 'name']). The method will automatically quote the column names unless a column contains some parenthesis (which means the column contains a DB expression).
Note that if your group-by is an expression containing commas, you should always use an array to represent the group-by information. Otherwise, the method will not be able to correctly determine the group-by columns.
Since version 2.0.7, an yii\db\Expression object can be passed to specify the GROUP BY part explicitly in plain SQL. Since version 2.0.14, an yii\db\ExpressionInterface object can be passed as well.
return $thisThe query object itself
public function addGroupBy($columns)
{
if ($columns instanceof ExpressionInterface) {
$columns = [$columns];
} elseif (!is_array($columns)) {
$columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY);
}
if ($this->groupBy === null) {
$this->groupBy = $columns;
} else {
$this->groupBy = array_merge($this->groupBy, $columns);
}
return $this;
}
public $this addOrderBy ( $columns ) $columns string|array|yii\db\ExpressionInterface
The columns (and the directions) to be ordered by. Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array (e.g. ['id' => SORT_ASC, 'name' => SORT_DESC]
).
The method will automatically quote the column names unless a column contains some parenthesis (which means the column contains a DB expression).
Note that if your order-by is an expression containing commas, you should always use an array to represent the order-by information. Otherwise, the method will not be able to correctly determine the order-by columns.
Since version 2.0.7, an yii\db\ExpressionInterface object can be passed to specify the ORDER BY part explicitly in plain SQL.
return $thisThe query object itself
public function addOrderBy($columns)
{
$columns = $this->normalizeOrderBy($columns);
if ($this->orderBy === null) {
$this->orderBy = $columns;
} else {
$this->orderBy = array_merge($this->orderBy, $columns);
}
return $this;
}
public $this addParams ( $params ) $params array
List of query parameter values indexed by parameter placeholders. For example, [':name' => 'Dan', ':age' => 31]
.
The query object itself
public function addParams($params)
{
if (!empty($params)) {
if (empty($this->params)) {
$this->params = $params;
} else {
foreach ($params as $name => $value) {
if (is_int($name)) {
$this->params[] = $value;
} else {
$this->params[$name] = $value;
}
}
}
}
return $this;
}
Defined in: yii\db\Query::addSelect()
Add more columns to the SELECT part of the query.
Note, that if select() has not been specified before, you should include *
explicitly if you want to select all remaining columns too:
$query->addSelect(["*", "CONCAT(first_name, ' ', last_name) AS full_name"])->one();
See also select().
public function addSelect($columns)
{
if ($this->select === null) {
return $this->select($columns);
}
if (!is_array($this->select)) {
$this->select = $this->normalizeSelect($this->select);
}
$this->select = array_merge($this->select, $this->normalizeSelect($columns));
return $this;
}
Define an alias for the table defined in $modelClass.
This method will adjust from() so that an already defined alias will be overwritten. If none was defined, from() will be populated with the given alias.
public function alias($alias)
{
if (empty($this->from) || count($this->from) < 2) {
list($tableName) = $this->getTableNameAndAlias();
$this->from = [$alias => $tableName];
} else {
$tableName = $this->getPrimaryTableName();
foreach ($this->from as $key => $table) {
if ($table === $tableName) {
unset($this->from[$key]);
$this->from[$alias] = $tableName;
}
}
}
return $this;
}
Executes query and returns all results as an array.
public function all($db = null)
{
return parent::all($db);
}
Defined in: yii\db\Query::andFilterCompare()
Adds a filtering condition for a specific column and allow the user to choose a filter operator.
It adds an additional WHERE condition for the given field and determines the comparison operator based on the first few characters of the given value. The condition is added in the same way as in andFilterWhere() so empty values are ignored. The new condition and the existing one will be joined using the AND
operator.
The comparison operator is intelligently determined based on the first few characters in the given value. In particular, it recognizes the following operators if they appear as the leading characters in the given value:
<
: the column must be less than the given value.>
: the column must be greater than the given value.<=
: the column must be less than or equal to the given value.>=
: the column must be greater than or equal to the given value.<>
: the column must not be the same as the given value.=
: the column must be equal to the given value.$defaultOperator
will be used.The column name.
$value stringThe column value optionally prepended with the comparison operator.
$defaultOperator stringThe operator to use, when no operator is given in $value
. Defaults to =
, performing an exact match.
The query object itself
public function andFilterCompare($name, $value, $defaultOperator = '=')
{
if (preg_match('/^(<>|>=|>|<=|<|=)/', (string)$value, $matches)) {
$operator = $matches[1];
$value = substr($value, strlen($operator));
} else {
$operator = $defaultOperator;
}
return $this->andFilterWhere([$operator, $name, $value]);
}
public function andFilterHaving(array $condition)
{
$condition = $this->filterCondition($condition);
if ($condition !== []) {
$this->andHaving($condition);
}
return $this;
}
public function andFilterWhere(array $condition)
{
$condition = $this->filterCondition($condition);
if ($condition !== []) {
$this->andWhere($condition);
}
return $this;
}
public function andHaving($condition, $params = [])
{
if ($this->having === null) {
$this->having = $condition;
} else {
$this->having = ['and', $this->having, $condition];
}
$this->addParams($params);
return $this;
}
Adds an additional ON condition to the existing one.
The new condition and the existing one will be joined using the 'AND' operator.
See also:
public $this andOnCondition ( $condition, $params = [] ) $condition string|arrayThe new ON condition. Please refer to where() on how to specify this parameter.
$params arrayThe parameters (name => value) to be bound to the query.
return $thisThe query object itself
public function andOnCondition($condition, $params = [])
{
if ($this->on === null) {
$this->on = $condition;
} else {
$this->on = ['and', $this->on, $condition];
}
$this->addParams($params);
return $this;
}
public function andWhere($condition)
{
if ($this->where === null) {
$this->where = $condition;
} else {
$this->where = ['and', $this->where, $condition];
}
return $this;
}
public $this asArray ( $value = true ) $value boolean
Whether to return the query results in terms of arrays instead of Active Records.
return $thisThe query object itself
public function asArray($value = true)
{
$this->asArray = $value;
return $this;
}
public function attachBehavior($name, $behavior)
{
$this->ensureBehaviors();
return $this->attachBehaviorInternal($name, $behavior);
}
public void attachBehaviors ( $behaviors ) $behaviors array
List of behaviors to be attached to the component
public function attachBehaviors($behaviors)
{
$this->ensureBehaviors();
foreach ($behaviors as $name => $behavior) {
$this->attachBehaviorInternal($name, $behavior);
}
}
public mixed average ( $q, $db = null ) $q string
The column name or expression. Make sure you properly quote column names in the expression.
$db yii\db\Connection|nullThe database connection used to generate the SQL statement. If this parameter is not given, the db
application component will be used.
The average of the specified column values.
public function average($q, $db = null)
{
if ($this->emulateExecution) {
return 0;
}
return $this->queryScalar("AVG($q)", $db);
}
Starts a batch query.
A batch query supports fetching data in batches, which can keep the memory usage under a limit. This method will return a yii\db\BatchQueryResult object which implements the Iterator interface and can be traversed to retrieve the data in batches.
For example,
$query = (new Query)->from('user');
foreach ($query->batch() as $rows) {
}
public function batch($batchSize = 100, $db = null)
{
return parent::batch($batchSize, $db);
}
Defined in: yii\base\Component::behaviors()
Returns a list of behaviors that this component should behave as.
Child classes may override this method to specify the behaviors they want to behave as.
The return value of this method should be an array of behavior objects or configurations indexed by behavior names. A behavior configuration can be either a string specifying the behavior class or an array of the following structure:
'behaviorName' => [
'class' => 'BehaviorClass',
'property1' => 'value1',
'property2' => 'value2',
]
Note that a behavior class must extend from yii\base\Behavior. Behaviors can be attached using a name or anonymously. When a name is used as the array key, using this name, the behavior can later be retrieved using getBehavior() or be detached using detachBehavior(). Anonymous behaviors can not be retrieved or detached.
Behaviors declared in this method will be attached to the component automatically (on demand).
public function behaviors()
{
return [];
}
public $this cache ( $duration = true, $dependency = null ) $duration integer|true
The number of seconds that query results can remain valid in cache. Use 0 to indicate that the cached data will never expire. Use a negative number to indicate that query cache should not be used. Use boolean true
to indicate that yii\db\Connection::$queryCacheDuration should be used. Defaults to true
.
The cache dependency associated with the cached result.
return $thisThe Query object itself
public function cache($duration = true, $dependency = null)
{
$this->queryCacheDuration = $duration;
$this->queryCacheDependency = $dependency;
return $this;
}
Defined in: yii\base\Component::canGetProperty()
Returns a value indicating whether a property can be read.
A property can be read if:
$checkVars
is true);$checkBehaviors
is true).See also canSetProperty().
public boolean canGetProperty ( $name, $checkVars = true, $checkBehaviors = true ) $name stringThe property name
$checkVars booleanWhether to treat member variables as properties
$checkBehaviors booleanWhether to treat behaviors' properties as properties of this component
return booleanWhether the property can be read
public function canGetProperty($name, $checkVars = true, $checkBehaviors = true)
{
if (method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name)) {
return true;
} elseif ($checkBehaviors) {
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canGetProperty($name, $checkVars)) {
return true;
}
}
}
return false;
}
Defined in: yii\base\Component::canSetProperty()
Returns a value indicating whether a property can be set.
A property can be written if:
$checkVars
is true);$checkBehaviors
is true).See also canGetProperty().
public boolean canSetProperty ( $name, $checkVars = true, $checkBehaviors = true ) $name stringThe property name
$checkVars booleanWhether to treat member variables as properties
$checkBehaviors booleanWhether to treat behaviors' properties as properties of this component
return booleanWhether the property can be written
public function canSetProperty($name, $checkVars = true, $checkBehaviors = true)
{
if (method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name)) {
return true;
} elseif ($checkBehaviors) {
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canSetProperty($name, $checkVars)) {
return true;
}
}
}
return false;
}
Deprecated since 2.0.14. On PHP >=5.5, use ::class
instead.
public static function className()
{
return get_called_class();
}
protected function cleanUpTableNames($tableNames)
{
$cleanedUpTableNames = [];
foreach ($tableNames as $alias => $tableName) {
if (is_string($tableName) && !is_string($alias)) {
$pattern = <<<PATTERN
'"`\[]|{{)
'"`\]]|}})
?\)
\s+
(?:as)?
\s*
?:['"`\[]|{{)
.*?
(?:['"`\]]|}})
|
.*?
ERN;
if (preg_match($pattern, $tableName, $matches)) {
if (isset($matches[2])) {
list(, $tableName, $alias) = $matches;
} else {
$tableName = $alias = $matches[1];
}
}
}
if ($tableName instanceof Expression) {
if (!is_string($alias)) {
throw new InvalidArgumentException('To use Expression in from() method, pass it in array format with alias.');
}
$cleanedUpTableNames[$this->ensureNameQuoted($alias)] = $tableName;
} elseif ($tableName instanceof self) {
$cleanedUpTableNames[$this->ensureNameQuoted($alias)] = $tableName;
} else {
$cleanedUpTableNames[$this->ensureNameQuoted($alias)] = $this->ensureNameQuoted($tableName);
}
}
return $cleanedUpTableNames;
}
public array column ( $db = null ) $db yii\db\Connection|null
The database connection used to generate the SQL statement. If this parameter is not given, the db
application component will be used.
The first column of the query result. An empty array is returned if the query results in nothing.
public function column($db = null)
{
if ($this->emulateExecution) {
return [];
}
if ($this->indexBy === null) {
return $this->createCommand($db)->queryColumn();
}
if (is_string($this->indexBy) && is_array($this->select) && count($this->select) === 1) {
if (strpos($this->indexBy, '.') === false && count($tables = $this->getTablesUsedInFrom()) > 0) {
$this->select[] = key($tables) . '.' . $this->indexBy;
} else {
$this->select[] = $this->indexBy;
}
}
$rows = $this->createCommand($db)->queryAll();
$results = [];
$column = null;
if (is_string($this->indexBy)) {
if (($dotPos = strpos($this->indexBy, '.')) === false) {
$column = $this->indexBy;
} else {
$column = substr($this->indexBy, $dotPos + 1);
}
}
foreach ($rows as $row) {
$value = reset($row);
if ($this->indexBy instanceof \Closure) {
$results[call_user_func($this->indexBy, $row)] = $value;
} else {
$results[$row[$column]] = $value;
}
}
return $results;
}
public integer|string|null count ( $q = '*', $db = null ) $q string
The COUNT expression. Defaults to '*'. Make sure you properly quote column names in the expression.
$db yii\db\Connection|nullThe database connection used to generate the SQL statement. If this parameter is not given (or null), the db
application component will be used.
Number of records. The result may be a string depending on the underlying database engine and to support integer values higher than a 32bit PHP integer can handle.
public function count($q = '*', $db = null)
{
if ($this->emulateExecution) {
return 0;
}
return $this->queryScalar("COUNT($q)", $db);
}
Defined in: yii\db\Query::create()
Creates a new Query object and copies its property values from an existing one.
The properties being copies are the ones to be used by query builders.
public static function create($from)
{
return new self([
'where' => $from->where,
'limit' => $from->limit,
'offset' => $from->offset,
'orderBy' => $from->orderBy,
'indexBy' => $from->indexBy,
'select' => $from->select,
'selectOption' => $from->selectOption,
'distinct' => $from->distinct,
'from' => $from->from,
'groupBy' => $from->groupBy,
'join' => $from->join,
'having' => $from->having,
'union' => $from->union,
'params' => $from->params,
'withQueries' => $from->withQueries,
]);
}
Creates a DB command that can be used to execute this query.
public function createCommand($db = null)
{
$modelClass = $this->modelClass;
if ($db === null) {
$db = $modelClass::getDb();
}
if ($this->sql === null) {
list($sql, $params) = $db->getQueryBuilder()->build($this);
} else {
$sql = $this->sql;
$params = $this->params;
}
$command = $db->createCommand($sql, $params);
$this->setCommandCache($command);
return $command;
}
protected function createModels($rows)
{
if ($this->asArray) {
return $rows;
} else {
$models = [];
$class = $this->modelClass;
foreach ($rows as $row) {
$model = $class::instantiate($row);
$modelClass = get_class($model);
$modelClass::populateRecord($model, $row);
$models[] = $model;
}
return $models;
}
}
public function detachBehavior($name)
{
$this->ensureBehaviors();
if (isset($this->_behaviors[$name])) {
$behavior = $this->_behaviors[$name];
unset($this->_behaviors[$name]);
$behavior->detach();
return $behavior;
}
return null;
}
public function detachBehaviors()
{
$this->ensureBehaviors();
foreach ($this->_behaviors as $name => $behavior) {
$this->detachBehavior($name);
}
}
public $this distinct ( $value = true ) $value boolean
Whether to SELECT DISTINCT or not.
return $thisThe query object itself
public function distinct($value = true)
{
$this->distinct = $value;
return $this;
}
Starts a batch query and retrieves data row by row.
This method is similar to batch() except that in each iteration of the result, only one row of data is returned. For example,
$query = (new Query)->from('user');
foreach ($query->each() as $row) {
}
public function each($batchSize = 100, $db = null)
{
return parent::each($batchSize, $db);
}
public function emulateExecution($value = true)
{
$this->emulateExecution = $value;
return $this;
}
public function ensureBehaviors()
{
if ($this->_behaviors === null) {
$this->_behaviors = [];
foreach ($this->behaviors() as $name => $behavior) {
$this->attachBehaviorInternal($name, $behavior);
}
}
}
Defined in: yii\db\Query::exists()
Returns a value indicating whether the query result contains any row of data.
public boolean exists ( $db = null ) $db yii\db\Connection|nullThe database connection used to generate the SQL statement. If this parameter is not given, the db
application component will be used.
Whether the query result contains any row of data.
public function exists($db = null)
{
if ($this->emulateExecution) {
return false;
}
$command = $this->createCommand($db);
$params = $command->params;
$command->setSql($command->db->getQueryBuilder()->selectExists($command->getSql()));
$command->bindValues($params);
return (bool) $command->queryScalar();
}
protected function filterCondition($condition)
{
if (!is_array($condition)) {
return $condition;
}
if (!isset($condition[0])) {
foreach ($condition as $name => $value) {
if ($this->isEmpty($value)) {
unset($condition[$name]);
}
}
return $condition;
}
$operator = array_shift($condition);
switch (strtoupper($operator)) {
case 'NOT':
case 'AND':
case 'OR':
foreach ($condition as $i => $operand) {
$subCondition = $this->filterCondition($operand);
if ($this->isEmpty($subCondition)) {
unset($condition[$i]);
} else {
$condition[$i] = $subCondition;
}
}
if (empty($condition)) {
return [];
}
break;
case 'BETWEEN':
case 'NOT BETWEEN':
if (array_key_exists(1, $condition) && array_key_exists(2, $condition)) {
if ($this->isEmpty($condition[1]) || $this->isEmpty($condition[2])) {
return [];
}
}
break;
default:
if (array_key_exists(1, $condition) && $this->isEmpty($condition[1])) {
return [];
}
}
array_unshift($condition, $operator);
return $condition;
}
Defined in: yii\db\Query::filterHaving()
Sets the HAVING part of the query but ignores empty operands.
This method is similar to having(). The main difference is that this method will remove empty query operands. As a result, this method is best suited for building query conditions based on filter values entered by users.
The following code shows the difference between this method and having():
$query->filterHaving(['name' => null, 'age' => 20]);
$query->having(['age' => 20]);
$query->having(['name' => null, 'age' => 20]);
Note that unlike having(), you cannot pass binding parameters to this method.
See also:
public $this filterHaving ( array $condition ) $condition arrayThe conditions that should be put in the HAVING part. See having() on how to specify this parameter.
return $thisThe query object itself
public function filterHaving(array $condition)
{
$condition = $this->filterCondition($condition);
if ($condition !== []) {
$this->having($condition);
}
return $this;
}
Defined in: yii\db\QueryTrait::filterWhere()
Sets the WHERE part of the query but ignores empty operands.
This method is similar to where(). The main difference is that this method will remove empty query operands. As a result, this method is best suited for building query conditions based on filter values entered by users.
The following code shows the difference between this method and where():
$query->filterWhere(['name' => null, 'age' => 20]);
$query->where(['age' => 20]);
$query->where(['name' => null, 'age' => 20]);
Note that unlike where(), you cannot pass binding parameters to this method.
See also:
public $this filterWhere ( array $condition ) $condition arrayThe conditions that should be put in the WHERE part. See where() on how to specify this parameter.
return $thisThe query object itself
public function filterWhere(array $condition)
{
$condition = $this->filterCondition($condition);
if ($condition !== []) {
$this->where($condition);
}
return $this;
}
Defined in: yii\db\ActiveRelationTrait::findFor()
Finds the related records for the specified primary record.
This method is invoked when a relation of an ActiveRecord is being accessed lazily.
public function findFor($name, $model)
{
if (method_exists($model, 'get' . $name)) {
$method = new \ReflectionMethod($model, 'get' . $name);
$realName = lcfirst(substr($method->getName(), 3));
if ($realName !== $name) {
throw new InvalidArgumentException('Relation names are case sensitive. ' . get_class($model) . " has a relation named \"$realName\" instead of \"$name\".");
}
}
return $this->multiple ? $this->all() : $this->one();
}
public void findWith ( $with, &$models ) $with array
A list of relations that this query should be performed with. Please refer to with() for details about specifying this parameter.
$models array|yii\db\ActiveRecord[]The primary models (can be either AR instances or arrays)
public function findWith($with, &$models)
{
if (empty($models)) {
return;
}
$primaryModel = reset($models);
if (!$primaryModel instanceof ActiveRecordInterface) {
$modelClass = $this->modelClass;
$primaryModel = $modelClass::instance();
}
$relations = $this->normalizeRelations($primaryModel, $with);
foreach ($relations as $name => $relation) {
if ($relation->asArray === null) {
$relation->asArray($this->asArray);
}
$relation->populateRelation($name, $models);
}
}
public $this from ( $tables ) $tables string|array|yii\db\ExpressionInterface
The table(s) to be selected from. This can be either a string (e.g. 'user'
) or an array (e.g. ['user', 'profile']
) specifying one or several table names. Table names can contain schema prefixes (e.g. 'public.user'
) and/or table aliases (e.g. 'user u'
). The method will automatically quote the table names unless it contains some parenthesis (which means the table is given as a sub-query or DB expression).
When the tables are specified as an array, you may also use the array keys as the table aliases (if a table does not need alias, do not use a string key).
Use a Query object to represent a sub-query. In this case, the corresponding array key will be used as the alias for the sub-query.
To specify the FROM
part in plain SQL, you may pass an instance of yii\db\ExpressionInterface.
Here are some examples:
$query = (new \yii\db\Query)->from(['u' => 'user', 'profile']);
$subquery = (new \yii\db\Query)->from('user')->where(['active' => true])
$query = (new \yii\db\Query)->from(['activeusers' => $subquery]);
$subquery = "(SELECT * FROM `user` WHERE `active` = 1)";
$query = (new \yii\db\Query)->from(['activeusers' => $subquery]);
return $this
The query object itself
public function from($tables)
{
if ($tables instanceof ExpressionInterface) {
$tables = [$tables];
}
if (is_string($tables)) {
$tables = preg_split('/\s*,\s*/', trim($tables), -1, PREG_SPLIT_NO_EMPTY);
}
$this->from = $tables;
return $this;
}
public function getBehavior($name)
{
$this->ensureBehaviors();
return isset($this->_behaviors[$name]) ? $this->_behaviors[$name] : null;
}
public function getBehaviors()
{
$this->ensureBehaviors();
return $this->_behaviors;
}
protected function getPrimaryTableName()
{
$modelClass = $this->modelClass;
return $modelClass::tableName();
}
Returns the table name and the table alias for $modelClass.
protected function getTableNameAndAlias()
{
if (empty($this->from)) {
$tableName = $this->getPrimaryTableName();
} else {
$tableName = '';
foreach ($this->from as $alias => $tableName) {
if (is_string($alias)) {
return [$tableName, $alias];
}
break;
}
}
if (preg_match('/^(.*?)\s+({{\w+}}|\w+)$/', $tableName, $matches)) {
$alias = $matches[2];
} else {
$alias = $tableName;
}
return [$tableName, $alias];
}
Returns table names used in from() indexed by aliases.
Both aliases and names are enclosed into {{ and }}.
public function getTablesUsedInFrom()
{
if (empty($this->from)) {
return $this->cleanUpTableNames([$this->getPrimaryTableName()]);
}
return parent::getTablesUsedInFrom();
}
Deprecated in 2.0.21
protected function getUnaliasedColumnsFromSelect()
{
$result = [];
if (is_array($this->select)) {
foreach ($this->select as $name => $value) {
if (is_int($name)) {
$result[] = $value;
}
}
}
return array_unique($result);
}
Deprecated in 2.0.21
Defined in: yii\db\Query::getUniqueColumns()
Returns unique column names excluding duplicates.
Columns to be removed:
protected function getUniqueColumns($columns)
{
$unaliasedColumns = $this->getUnaliasedColumnsFromSelect();
$result = [];
foreach ($columns as $columnAlias => $columnDefinition) {
if (!$columnDefinition instanceof Query) {
if (is_string($columnAlias)) {
$existsInSelect = isset($this->select[$columnAlias]) && $this->select[$columnAlias] === $columnDefinition;
if ($existsInSelect) {
continue;
}
} elseif (is_int($columnAlias)) {
$existsInSelect = in_array($columnDefinition, $unaliasedColumns, true);
$existsInResultSet = in_array($columnDefinition, $result, true);
if ($existsInSelect || $existsInResultSet) {
continue;
}
}
}
$result[$columnAlias] = $columnDefinition;
}
return $result;
}
public $this groupBy ( $columns ) $columns string|array|yii\db\ExpressionInterface|null
The columns to be grouped by. Columns can be specified in either a string (e.g. "id, name") or an array (e.g. ['id', 'name']). The method will automatically quote the column names unless a column contains some parenthesis (which means the column contains a DB expression).
Note that if your group-by is an expression containing commas, you should always use an array to represent the group-by information. Otherwise, the method will not be able to correctly determine the group-by columns.
Since version 2.0.7, an yii\db\ExpressionInterface object can be passed to specify the GROUP BY part explicitly in plain SQL. Since version 2.0.14, an yii\db\ExpressionInterface object can be passed as well.
return $thisThe query object itself
public function groupBy($columns)
{
if ($columns instanceof ExpressionInterface) {
$columns = [$columns];
} elseif (!is_array($columns) && !is_null($columns)) {
$columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY);
}
$this->groupBy = $columns;
return $this;
}
public function hasEventHandlers($name)
{
$this->ensureBehaviors();
if (!empty($this->_events[$name])) {
return true;
}
foreach ($this->_eventWildcards as $wildcard => $handlers) {
if (!empty($handlers) && StringHelper::matchWildcard($wildcard, $name)) {
return true;
}
}
return Event::hasHandlers($this, $name);
}
Defined in: yii\base\Component::hasMethod()
Returns a value indicating whether a method is defined.
A method is defined if:
$checkBehaviors
is true).The property name
$checkBehaviors booleanWhether to treat behaviors' methods as methods of this component
return booleanWhether the method is defined
public function hasMethod($name, $checkBehaviors = true)
{
if (method_exists($this, $name)) {
return true;
} elseif ($checkBehaviors) {
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->hasMethod($name)) {
return true;
}
}
}
return false;
}
Defined in: yii\base\Component::hasProperty()
Returns a value indicating whether a property is defined for this component.
A property is defined if:
$checkVars
is true);$checkBehaviors
is true).See also:
public boolean hasProperty ( $name, $checkVars = true, $checkBehaviors = true ) $name stringThe property name
$checkVars booleanWhether to treat member variables as properties
$checkBehaviors booleanWhether to treat behaviors' properties as properties of this component
return booleanWhether the property is defined
public function hasProperty($name, $checkVars = true, $checkBehaviors = true)
{
return $this->canGetProperty($name, $checkVars, $checkBehaviors) || $this->canSetProperty($name, false, $checkBehaviors);
}
public function having($condition, $params = [])
{
$this->having = $condition;
$this->addParams($params);
return $this;
}
public $this indexBy ( $column ) $column string|callable
The name of the column by which the query results should be indexed by. This can also be a callable (e.g. anonymous function) that returns the index value based on the given row data. The signature of the callable should be:
function ($row)
{
}
return $this
The query object itself
public function indexBy($column)
{
$this->indexBy = $column;
return $this;
}
Initializes the object.
This method is called at the end of the constructor. The default implementation will trigger an EVENT_INIT event. If you override this method, make sure you call the parent implementation at the end to ensure triggering of the event.
public function init()
{
parent::init();
$this->trigger(self::EVENT_INIT);
}
public $this innerJoin ( $table, $on = '', $params = [] ) $table string|array
The table or sub-query to be joined.
Use a string to represent the name of the table to be joined. The table name can contain a schema prefix (e.g. 'public.user') and/or table alias (e.g. 'user u'). The method will automatically quote the table name unless it contains some parenthesis (which means the table is given as a sub-query or DB expression).
You may also specify the table as an array with one element, using the array key as the table alias (e.g. ['u' => 'user']).
To join a sub-query, use an array with one element, with the value set to a yii\db\Query object representing the sub-query, and the corresponding key representing the alias.
$on string|arrayThe join condition that should appear in the ON part. Please refer to join() on how to specify this parameter.
$params arrayThe parameters (name => value) to be bound to the query.
return $thisThe query object itself
public function innerJoin($table, $on = '', $params = [])
{
$this->join[] = ['INNER JOIN', $table, $on];
return $this->addParams($params);
}
Inner joins with the specified relations.
This is a shortcut method to joinWith() with the join type set as "INNER JOIN". Please refer to joinWith() for detailed usage of this method.
See also joinWith().
public $this innerJoinWith ( $with, $eagerLoading = true ) $with string|arrayThe relations to be joined with.
$eagerLoading boolean|arrayWhether to eager load the relations. Note, that this does not mean, that the relations are populated from the query result. An extra query will still be performed to bring in the related data.
return $thisThe query object itself
public function innerJoinWith($with, $eagerLoading = true)
{
return $this->joinWith($with, $eagerLoading, 'INNER JOIN');
}
Defined in: yii\db\ActiveRelationTrait::inverseOf()
Sets the name of the relation that is the inverse of this relation.
For example, a customer has orders, which means the inverse of the "orders" relation is the "customer". If this property is set, the primary record(s) will be referenced through the specified relation. For example, $customer->orders[0]->customer
and $customer
will be the same object, and accessing the customer of an order will not trigger a new DB query.
Use this method when declaring a relation in the yii\db\ActiveRecord class, e.g. in Customer model:
public function getOrders()
{
return $this->hasMany(Order::class, ['customer_id' => 'id'])->inverseOf('customer');
}
This also may be used for Order model, but with caution:
public function getCustomer()
{
return $this->hasOne(Customer::class, ['id' => 'customer_id'])->inverseOf('orders');
}
in this case result will depend on how order(s) was loaded. Let's suppose customer has several orders. If only one order was loaded:
$orders = Order::find()->where(['id' => 1])->all();
$customerOrders = $orders[0]->customer->orders;
variable $customerOrders
will contain only one order. If orders was loaded like this:
$orders = Order::find()->with('customer')->where(['customer_id' => 1])->all();
$customerOrders = $orders[0]->customer->orders;
variable $customerOrders
will contain all orders of the customer.
The name of the relation that is the inverse of this relation.
return $thisThe relation object itself.
public function inverseOf($relationName)
{
$this->inverseOf = $relationName;
return $this;
}
Defined in: yii\db\QueryTrait::isEmpty()
Returns a value indicating whether the give value is "empty".
The value is considered "empty", if one of the following conditions is satisfied:
null
,''
), protected function isEmpty($value)
{
return $value === '' || $value === [] || $value === null || is_string($value) && trim($value) === '';
}
Defined in: yii\db\Query::join()
Appends a JOIN part to the query.
The first parameter specifies what type of join it is.
public $this join ( $type, $table, $on = '', $params = [] ) $type stringThe type of join, such as INNER JOIN, LEFT JOIN.
$table string|arrayThe table or sub-query to be joined.
Use a string to represent the name of the table to be joined. The table name can contain a schema prefix (e.g. 'public.user') and/or table alias (e.g. 'user u'). The method will automatically quote the table name unless it contains some parenthesis (which means the table is given as a sub-query or DB expression).
You may also specify the table as an array with one element, using the array key as the table alias (e.g. ['u' => 'user']).
To join a sub-query, use an array with one element, with the value set to a yii\db\Query object representing the sub-query, and the corresponding key representing the alias.
$on string|arrayThe join condition that should appear in the ON part. Please refer to where() on how to specify this parameter.
Note that the array format of where() is designed to match columns to values instead of columns to columns, so the following would not work as expected: ['post.author_id' => 'user.id']
, it would match the post.author_id
column value against the string 'user.id'
. It is recommended to use the string syntax here which is more suited for a join:
'post.author_id = user.id'
$params array
The parameters (name => value) to be bound to the query.
return $thisThe query object itself
public function join($type, $table, $on = '', $params = [])
{
$this->join[] = [$type, $table, $on];
return $this->addParams($params);
}
Joins with the specified relations.
This method allows you to reuse existing relation definitions to perform JOIN queries. Based on the definition of the specified relation(s), the method will append one or multiple JOIN statements to the current query.
If the $eagerLoading
parameter is true, the method will also perform eager loading for the specified relations, which is equivalent to calling with() using the specified relations.
Note that because a JOIN query will be performed, you are responsible to disambiguate column names.
This method differs from with() in that it will build up and execute a JOIN SQL statement for the primary table. And when $eagerLoading
is true, it will call with() in addition with the specified relations.
The relations to be joined. This can either be a string, representing a relation name or an array with the following semantics:
The relation name may optionally contain an alias for the relation table (e.g. books b
).
Sub-relations can also be specified, see with() for the syntax.
In the following you find some examples:
Order::find()->joinWith('books', true, 'INNER JOIN')->all();
Order::find()->joinWith([
'books' => function (\yii\db\ActiveQuery $query) {
$query->orderBy('item.name');
}
])->all();
Order::find()->joinWith(['books b'], true, 'INNER JOIN')->where(['b.category' => 'Science fiction'])->all();
The alias syntax is available since version 2.0.7.
$eagerLoading boolean|arrayWhether to eager load the relations specified in $with
. When this is a boolean, it applies to all relations specified in $with
. Use an array to explicitly list which relations in $with
need to be eagerly loaded. Note, that this does not mean, that the relations are populated from the query result. An extra query will still be performed to bring in the related data. Defaults to true
.
The join type of the relations specified in $with
. When this is a string, it applies to all relations specified in $with
. Use an array in the format of relationName => joinType
to specify different join types for different relations.
The query object itself
public function joinWith($with, $eagerLoading = true, $joinType = 'LEFT JOIN')
{
$relations = [];
foreach ((array) $with as $name => $callback) {
if (is_int($name)) {
$name = $callback;
$callback = null;
}
if (preg_match('/^(.*?)(?:\s+AS\s+|\s+)(\w+)$/i', $name, $matches)) {
list(, $relation, $alias) = $matches;
$name = $relation;
$callback = function ($query) use ($callback, $alias) {
$query->alias($alias);
if ($callback !== null) {
call_user_func($callback, $query);
}
};
}
if ($callback === null) {
$relations[] = $name;
} else {
$relations[$name] = $callback;
}
}
$this->joinWith[] = [$relations, $eagerLoading, $joinType];
return $this;
}
public $this leftJoin ( $table, $on = '', $params = [] ) $table string|array
The table or sub-query to be joined.
Use a string to represent the name of the table to be joined. The table name can contain a schema prefix (e.g. 'public.user') and/or table alias (e.g. 'user u'). The method will automatically quote the table name unless it contains some parenthesis (which means the table is given as a sub-query or DB expression).
You may also specify the table as an array with one element, using the array key as the table alias (e.g. ['u' => 'user']).
To join a sub-query, use an array with one element, with the value set to a yii\db\Query object representing the sub-query, and the corresponding key representing the alias.
$on string|arrayThe join condition that should appear in the ON part. Please refer to join() on how to specify this parameter.
$params arrayThe parameters (name => value) to be bound to the query
return $thisThe query object itself
public function leftJoin($table, $on = '', $params = [])
{
$this->join[] = ['LEFT JOIN', $table, $on];
return $this->addParams($params);
}
public function limit($limit)
{
$this->limit = $limit;
return $this;
}
public mixed max ( $q, $db = null ) $q string
The column name or expression. Make sure you properly quote column names in the expression.
$db yii\db\Connection|nullThe database connection used to generate the SQL statement. If this parameter is not given, the db
application component will be used.
The maximum of the specified column values.
public function max($q, $db = null)
{
return $this->queryScalar("MAX($q)", $db);
}
public mixed min ( $q, $db = null ) $q string
The column name or expression. Make sure you properly quote column names in the expression.
$db yii\db\Connection|nullThe database connection used to generate the SQL statement. If this parameter is not given, the db
application component will be used.
The minimum of the specified column values.
public function min($q, $db = null)
{
return $this->queryScalar("MIN($q)", $db);
}
public function noCache()
{
$this->queryCacheDuration = -1;
return $this;
}
protected function normalizeOrderBy($columns)
{
if (empty($columns)) {
return [];
} elseif ($columns instanceof ExpressionInterface) {
return [$columns];
} elseif (is_array($columns)) {
return $columns;
}
$columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY);
$result = [];
foreach ($columns as $column) {
if (preg_match('/^(.*?)\s+(asc|desc)$/i', $column, $matches)) {
$result[$matches[1]] = strcasecmp($matches[2], 'desc') ? SORT_ASC : SORT_DESC;
} else {
$result[$column] = SORT_ASC;
}
}
return $result;
}
protected function normalizeSelect($columns)
{
if ($columns instanceof ExpressionInterface) {
$columns = [$columns];
} elseif (!is_array($columns)) {
$columns = preg_split('/\s*,\s*/', trim((string)$columns), -1, PREG_SPLIT_NO_EMPTY);
}
$select = [];
foreach ($columns as $columnAlias => $columnDefinition) {
if (is_string($columnAlias)) {
$select[$columnAlias] = $columnDefinition;
continue;
}
if (is_string($columnDefinition)) {
if (
preg_match('/^(.*?)(?i:\s+as\s+|\s+)([\w\-_\.]+)$/', $columnDefinition, $matches) &&
!preg_match('/^\d+$/', $matches[2]) &&
strpos($matches[2], '.') === false
) {
$select[$matches[2]] = $matches[1];
continue;
}
if (strpos($columnDefinition, '(') === false) {
$select[$columnDefinition] = $columnDefinition;
continue;
}
}
$select[] = $columnDefinition;
}
return $select;
}
Defined in: yii\base\Component::off()
Detaches an existing event handler from this component.
This method is the opposite of on().
Note: in case wildcard pattern is passed for event name, only the handlers registered with this wildcard will be removed, while handlers registered with plain names matching this wildcard will remain.
See also on().
public boolean off ( $name, $handler = null ) $name stringEvent name
$handler callable|nullThe event handler to be removed. If it is null, all handlers attached to the named event will be removed.
return booleanIf a handler is found and detached
public function off($name, $handler = null)
{
$this->ensureBehaviors();
if (empty($this->_events[$name]) && empty($this->_eventWildcards[$name])) {
return false;
}
if ($handler === null) {
unset($this->_events[$name], $this->_eventWildcards[$name]);
return true;
}
$removed = false;
if (isset($this->_events[$name])) {
foreach ($this->_events[$name] as $i => $event) {
if ($event[0] === $handler) {
unset($this->_events[$name][$i]);
$removed = true;
}
}
if ($removed) {
$this->_events[$name] = array_values($this->_events[$name]);
return true;
}
}
if (isset($this->_eventWildcards[$name])) {
foreach ($this->_eventWildcards[$name] as $i => $event) {
if ($event[0] === $handler) {
unset($this->_eventWildcards[$name][$i]);
$removed = true;
}
}
if ($removed) {
$this->_eventWildcards[$name] = array_values($this->_eventWildcards[$name]);
if (empty($this->_eventWildcards[$name])) {
unset($this->_eventWildcards[$name]);
}
}
}
return $removed;
}
public function offset($offset)
{
$this->offset = $offset;
return $this;
}
Defined in: yii\base\Component::on()
Attaches an event handler to an event.
The event handler must be a valid PHP callback. The following are some examples:
function ($event) { ... }
[$object, 'handleClick']
['Page', 'handleClick']
'handleClick'
The event handler must be defined with the following signature,
function ($event)
where $event
is an yii\base\Event object which includes parameters associated with the event.
Since 2.0.14 you can specify event name as a wildcard pattern:
$component->on('event.group.*', function ($event) {
Yii::trace($event->name . ' is triggered.');
});
See also off().
public void on ( $name, $handler, $data = null, $append = true ) $name stringThe event name
$handler callableThe event handler
$data mixedThe data to be passed to the event handler when the event is triggered. When the event handler is invoked, this data can be accessed via yii\base\Event::$data.
$append booleanWhether to append new event handler to the end of the existing handler list. If false, the new handler will be inserted at the beginning of the existing handler list.
public function on($name, $handler, $data = null, $append = true)
{
$this->ensureBehaviors();
if (strpos($name, '*') !== false) {
if ($append || empty($this->_eventWildcards[$name])) {
$this->_eventWildcards[$name][] = [$handler, $data];
} else {
array_unshift($this->_eventWildcards[$name], [$handler, $data]);
}
return;
}
if ($append || empty($this->_events[$name])) {
$this->_events[$name][] = [$handler, $data];
} else {
array_unshift($this->_events[$name], [$handler, $data]);
}
}
Sets the ON condition for a relational query.
The condition will be used in the ON part when yii\db\ActiveQuery::joinWith() is called. Otherwise, the condition will be used in the WHERE part of a query.
Use this method to specify additional conditions when declaring a relation in the yii\db\ActiveRecord class:
public function getActiveUsers()
{
return $this->hasMany(User::class, ['id' => 'user_id'])
->onCondition(['active' => true]);
}
Note that this condition is applied in case of a join as well as when fetching the related records. Thus only fields of the related table can be used in the condition. Trying to access fields of the primary record will cause an error in a non-join-query.
public function onCondition($condition, $params = [])
{
$this->on = $condition;
$this->addParams($params);
return $this;
}
Executes query and returns a single row of result.
public function one($db = null)
{
$row = parent::one($db);
if ($row !== false) {
$models = $this->populate([$row]);
return reset($models) ?: null;
}
return null;
}
public function orFilterHaving(array $condition)
{
$condition = $this->filterCondition($condition);
if ($condition !== []) {
$this->orHaving($condition);
}
return $this;
}
public function orFilterWhere(array $condition)
{
$condition = $this->filterCondition($condition);
if ($condition !== []) {
$this->orWhere($condition);
}
return $this;
}
public function orHaving($condition, $params = [])
{
if ($this->having === null) {
$this->having = $condition;
} else {
$this->having = ['or', $this->having, $condition];
}
$this->addParams($params);
return $this;
}
Adds an additional ON condition to the existing one.
The new condition and the existing one will be joined using the 'OR' operator.
See also:
public $this orOnCondition ( $condition, $params = [] ) $condition string|arrayThe new ON condition. Please refer to where() on how to specify this parameter.
$params arrayThe parameters (name => value) to be bound to the query.
return $thisThe query object itself
public function orOnCondition($condition, $params = [])
{
if ($this->on === null) {
$this->on = $condition;
} else {
$this->on = ['or', $this->on, $condition];
}
$this->addParams($params);
return $this;
}
public function orWhere($condition)
{
if ($this->where === null) {
$this->where = $condition;
} else {
$this->where = ['or', $this->where, $condition];
}
return $this;
}
public $this orderBy ( $columns ) $columns string|array|yii\db\ExpressionInterface|null
The columns (and the directions) to be ordered by. Columns can be specified in either a string (e.g. "id ASC, name DESC"
) or an array (e.g. ['id' => SORT_ASC, 'name' => SORT_DESC]
).
The method will automatically quote the column names unless a column contains some parenthesis (which means the column contains a DB expression).
Note that if your order-by is an expression containing commas, you should always use an array to represent the order-by information. Otherwise, the method will not be able to correctly determine the order-by columns.
Since version 2.0.7, an yii\db\ExpressionInterface object can be passed to specify the ORDER BY part explicitly in plain SQL.
return $thisThe query object itself
public function orderBy($columns)
{
$this->orderBy = $this->normalizeOrderBy($columns);
return $this;
}
public $this params ( $params ) $params array
List of query parameter values indexed by parameter placeholders. For example, [':name' => 'Dan', ':age' => 31]
.
The query object itself
public function params($params)
{
$this->params = $params;
return $this;
}
Converts the raw query results into the format as specified by this query.
This method is internally used to convert the data fetched from database into the format as required by this query.
public array populate ( $rows ) $rows arrayThe raw query result from database
return arrayThe converted query result
public function populate($rows)
{
if (empty($rows)) {
return [];
}
$models = $this->createModels($rows);
if (!empty($this->join) && $this->indexBy === null) {
$models = $this->removeDuplicatedModels($models);
}
if (!empty($this->with)) {
$this->findWith($this->with, $models);
}
if ($this->inverseOf !== null) {
$this->addInverseRelations($models);
}
if (!$this->asArray) {
foreach ($models as $model) {
$model->afterFind();
}
}
return parent::populate($models);
}
public function populateRelation($name, &$primaryModels)
{
if (!is_array($this->link)) {
throw new InvalidConfigException('Invalid link: it must be an array of key-value pairs.');
}
if ($this->via instanceof self) {
$viaQuery = $this->via;
$viaModels = $viaQuery->findJunctionRows($primaryModels);
$this->filterByModels($viaModels);
} elseif (is_array($this->via)) {
list($viaName, $viaQuery) = $this->via;
if ($viaQuery->asArray === null) {
$viaQuery->asArray($this->asArray);
}
$viaQuery->primaryModel = null;
$viaModels = array_filter($viaQuery->populateRelation($viaName, $primaryModels));
$this->filterByModels($viaModels);
} else {
$this->filterByModels($primaryModels);
}
if (!$this->multiple && count($primaryModels) === 1) {
$model = $this->one();
$primaryModel = reset($primaryModels);
if ($primaryModel instanceof ActiveRecordInterface) {
$primaryModel->populateRelation($name, $model);
} else {
$primaryModels[key($primaryModels)][$name] = $model;
}
if ($this->inverseOf !== null) {
$this->populateInverseRelation($primaryModels, [$model], $name, $this->inverseOf);
}
return [$model];
}
$indexBy = $this->indexBy;
$this->indexBy = null;
$models = $this->all();
if (isset($viaModels, $viaQuery)) {
$buckets = $this->buildBuckets($models, $this->link, $viaModels, $viaQuery);
} else {
$buckets = $this->buildBuckets($models, $this->link);
}
$this->indexBy = $indexBy;
if ($this->indexBy !== null && $this->multiple) {
$buckets = $this->indexBuckets($buckets, $this->indexBy);
}
$link = array_values($this->link);
if (isset($viaQuery)) {
$deepViaQuery = $viaQuery;
while ($deepViaQuery->via) {
$deepViaQuery = is_array($deepViaQuery->via) ? $deepViaQuery->via[1] : $deepViaQuery->via;
};
$link = array_values($deepViaQuery->link);
}
foreach ($primaryModels as $i => $primaryModel) {
$keys = null;
if ($this->multiple && count($link) === 1) {
$primaryModelKey = reset($link);
$keys = isset($primaryModel[$primaryModelKey]) ? $primaryModel[$primaryModelKey] : null;
}
if (is_array($keys)) {
$value = [];
foreach ($keys as $key) {
$key = $this->normalizeModelKey($key);
if (isset($buckets[$key])) {
if ($this->indexBy !== null) {
foreach ($buckets[$key] as $bucketKey => $bucketValue) {
$value[$bucketKey] = $bucketValue;
}
} else {
$value = array_merge($value, $buckets[$key]);
}
}
}
} else {
$key = $this->getModelKey($primaryModel, $link);
$value = isset($buckets[$key]) ? $buckets[$key] : ($this->multiple ? [] : null);
}
if ($primaryModel instanceof ActiveRecordInterface) {
$primaryModel->populateRelation($name, $value);
} else {
$primaryModels[$i][$name] = $value;
}
}
if ($this->inverseOf !== null) {
$this->populateInverseRelation($primaryModels, $models, $name, $this->inverseOf);
}
return $models;
}
Prepares for building SQL.
This method is called by yii\db\QueryBuilder when it starts to build SQL from a query object. You may override this method to do some final preparation work when converting a query into a SQL statement.
public function prepare($builder)
{
if (!empty($this->joinWith)) {
$this->buildJoinWith();
$this->joinWith = null;
}
if (empty($this->from)) {
$this->from = [$this->getPrimaryTableName()];
}
if (empty($this->select) && !empty($this->join)) {
list(, $alias) = $this->getTableNameAndAlias();
$this->select = ["$alias.*"];
}
if ($this->primaryModel === null) {
$query = Query::create($this);
} else {
$where = $this->where;
if ($this->via instanceof self) {
$viaModels = $this->via->findJunctionRows([$this->primaryModel]);
$this->filterByModels($viaModels);
} elseif (is_array($this->via)) {
list($viaName, $viaQuery, $viaCallableUsed) = $this->via;
if ($viaQuery->multiple) {
if ($viaCallableUsed) {
$viaModels = $viaQuery->all();
} elseif ($this->primaryModel->isRelationPopulated($viaName)) {
$viaModels = $this->primaryModel->$viaName;
} else {
$viaModels = $viaQuery->all();
$this->primaryModel->populateRelation($viaName, $viaModels);
}
} else {
if ($viaCallableUsed) {
$model = $viaQuery->one();
} elseif ($this->primaryModel->isRelationPopulated($viaName)) {
$model = $this->primaryModel->$viaName;
} else {
$model = $viaQuery->one();
$this->primaryModel->populateRelation($viaName, $model);
}
$viaModels = $model === null ? [] : [$model];
}
$this->filterByModels($viaModels);
} else {
$this->filterByModels([$this->primaryModel]);
}
$query = Query::create($this);
$this->where = $where;
}
if (!empty($this->on)) {
$query->andWhere($this->on);
}
return $query;
}
Queries a scalar value by setting select() first.
Restores the value of select to make this query reusable.
protected function queryScalar($selectExpression, $db)
{
$modelClass = $this->modelClass;
if ($db === null) {
$db = $modelClass::getDb();
}
if ($this->sql === null) {
return parent::queryScalar($selectExpression, $db);
}
$command = (new Query())->select([$selectExpression])
->from(['c' => "({$this->sql})"])
->params($this->params)
->createCommand($db);
$this->setCommandCache($command);
return $command->queryScalar();
}
public $this rightJoin ( $table, $on = '', $params = [] ) $table string|array
The table or sub-query to be joined.
Use a string to represent the name of the table to be joined. The table name can contain a schema prefix (e.g. 'public.user') and/or table alias (e.g. 'user u'). The method will automatically quote the table name unless it contains some parenthesis (which means the table is given as a sub-query or DB expression).
You may also specify the table as an array with one element, using the array key as the table alias (e.g. ['u' => 'user']).
To join a sub-query, use an array with one element, with the value set to a yii\db\Query object representing the sub-query, and the corresponding key representing the alias.
$on string|arrayThe join condition that should appear in the ON part. Please refer to join() on how to specify this parameter.
$params arrayThe parameters (name => value) to be bound to the query
return $thisThe query object itself
public function rightJoin($table, $on = '', $params = [])
{
$this->join[] = ['RIGHT JOIN', $table, $on];
return $this->addParams($params);
}
Defined in: yii\db\Query::scalar()
Returns the query result as a scalar value.
The value returned will be the first column in the first row of the query results.
public string|integer|null|false scalar ( $db = null ) $db yii\db\Connection|nullThe database connection used to generate the SQL statement. If this parameter is not given, the db
application component will be used.
The value of the first column in the first row of the query result. False is returned if the query result is empty.
public function scalar($db = null)
{
if ($this->emulateExecution) {
return null;
}
return $this->createCommand($db)->queryScalar();
}
public $this select ( $columns, $option = null ) $columns string|array|yii\db\ExpressionInterface
The columns to be selected. Columns can be specified in either a string (e.g. "id, name") or an array (e.g. ['id', 'name']). Columns can be prefixed with table names (e.g. "user.id") and/or contain column aliases (e.g. "user.id AS user_id"). The method will automatically quote the column names unless a column contains some parenthesis (which means the column contains a DB expression). A DB expression may also be passed in form of an yii\db\ExpressionInterface object.
Note that if you are selecting an expression like CONCAT(first_name, ' ', last_name)
, you should use an array to specify the columns. Otherwise, the expression may be incorrectly split into several parts.
When the columns are specified as an array, you may also use array keys as the column aliases (if a column does not need alias, do not use a string key).
Starting from version 2.0.1, you may also select sub-queries as columns by specifying each such column as a Query
instance representing the sub-query.
Additional option that should be appended to the 'SELECT' keyword. For example, in MySQL, the option 'SQL_CALC_FOUND_ROWS' can be used.
return $thisThe query object itself
public function select($columns, $option = null)
{
$this->select = $this->normalizeSelect($columns);
$this->selectOption = $option;
return $this;
}
protected function setCommandCache($command)
{
if ($this->queryCacheDuration !== null || $this->queryCacheDependency !== null) {
$duration = $this->queryCacheDuration === true ? null : $this->queryCacheDuration;
$command->cache($duration, $this->queryCacheDependency);
}
return $command;
}
public mixed sum ( $q, $db = null ) $q string
The column name or expression. Make sure you properly quote column names in the expression.
$db yii\db\Connection|nullThe database connection used to generate the SQL statement. If this parameter is not given, the db
application component will be used.
The sum of the specified column values.
public function sum($q, $db = null)
{
if ($this->emulateExecution) {
return 0;
}
return $this->queryScalar("SUM($q)", $db);
}
Defined in: yii\base\Component::trigger()
Triggers an event.
This method represents the happening of an event. It invokes all attached handlers for the event including class-level handlers.
public function trigger($name, ?Event $event = null)
{
$this->ensureBehaviors();
$eventHandlers = [];
foreach ($this->_eventWildcards as $wildcard => $handlers) {
if (StringHelper::matchWildcard($wildcard, $name)) {
$eventHandlers[] = $handlers;
}
}
if (!empty($this->_events[$name])) {
$eventHandlers[] = $this->_events[$name];
}
if (!empty($eventHandlers)) {
$eventHandlers = call_user_func_array('array_merge', $eventHandlers);
if ($event === null) {
$event = new Event();
}
if ($event->sender === null) {
$event->sender = $this;
}
$event->handled = false;
$event->name = $name;
foreach ($eventHandlers as $handler) {
$event->data = $handler[1];
call_user_func($handler[0], $event);
if ($event->handled) {
return;
}
}
}
Event::trigger($this, $name, $event);
}
public $this union ( $sql, $all = false ) $sql string|yii\db\Query
The SQL statement to be appended using UNION
$all booleanTRUE if using UNION ALL and FALSE if using UNION
return $thisThe query object itself
public function union($sql, $all = false)
{
$this->union[] = ['query' => $sql, 'all' => $all];
return $this;
}
Defined in: yii\db\ActiveRelationTrait::via()
Specifies the relation associated with the junction table.
Use this method to specify a pivot record/table when declaring a relation in the yii\db\ActiveRecord class:
class Order extends ActiveRecord
{
public function getOrderItems() {
return $this->hasMany(OrderItem::class, ['order_id' => 'id']);
}
public function getItems() {
return $this->hasMany(Item::class, ['id' => 'item_id'])
->via('orderItems');
}
}
public $this via ( $relationName, ?callable $callable = null ) $relationName string
The relation name. This refers to a relation declared in $primaryModel.
$callable callable|nullA PHP callback for customizing the relation associated with the junction table. Its signature should be function($query)
, where $query
is the query to be customized.
The relation object itself.
public function via($relationName, ?callable $callable = null)
{
$relation = $this->primaryModel->getRelation($relationName);
$callableUsed = $callable !== null;
$this->via = [$relationName, $relation, $callableUsed];
if ($callable !== null) {
call_user_func($callable, $relation);
}
return $this;
}
Specifies the junction table for a relational query.
Use this method to specify a junction table when declaring a relation in the yii\db\ActiveRecord class:
public function getItems()
{
return $this->hasMany(Item::class, ['id' => 'item_id'])
->viaTable('order_item', ['order_id' => 'id']);
}
See also via().
public $this viaTable ( $tableName, $link, ?callable $callable = null ) $tableName stringThe name of the junction table.
$link arrayThe link between the junction table and the table associated with $primaryModel. The keys of the array represent the columns in the junction table, and the values represent the columns in the $primaryModel table.
$callable callable|nullA PHP callback for customizing the relation associated with the junction table. Its signature should be function($query)
, where $query
is the query to be customized.
The query object itself
throws yii\base\InvalidConfigExceptionwhen query is not initialized properly
public function viaTable($tableName, $link, ?callable $callable = null)
{
$modelClass = $this->primaryModel ? get_class($this->primaryModel) : $this->modelClass;
$relation = new self($modelClass, [
'from' => [$tableName],
'link' => $link,
'multiple' => true,
'asArray' => true,
]);
$this->via = $relation;
if ($callable !== null) {
call_user_func($callable, $relation);
}
return $this;
}
public function where($condition)
{
$this->where = $condition;
return $this;
}
Defined in: yii\db\ActiveQueryTrait::with()
Specifies the relations with which this query should be performed.
The parameters to this method can be either one or multiple strings, or a single array of relation names and the optional callbacks to customize the relations.
A relation name can refer to a relation defined in $modelClass or a sub-relation that stands for a relation of a related record. For example, orders.address
means the address
relation defined in the model class corresponding to the orders
relation.
The following are some usage examples:
Customer::find()->with('orders', 'country')->all();
Customer::find()->with('orders.address')->all();
Customer::find()->with([
'orders' => function (\yii\db\ActiveQuery $query) {
$query->andWhere('status = 1');
},
'country',
])->all();
You can call with()
multiple times. Each call will add relations to the existing ones. For example, the following two statements are equivalent:
Customer::find()->with('orders', 'country')->all();
Customer::find()->with('orders')->with('country')->all();
public function with()
{
$with = func_get_args();
if (isset($with[0]) && is_array($with[0])) {
$with = $with[0];
}
if (empty($this->with)) {
$this->with = $with;
} elseif (!empty($with)) {
foreach ($with as $name => $value) {
if (is_int($name)) {
$this->with[] = $value;
} else {
$this->with[$name] = $value;
}
}
}
return $this;
}
public $this withQuery ( $query, $alias, $recursive = false ) $query string|yii\db\Query
The SQL statement to be prepended using WITH
$alias stringQuery alias in WITH construction
$recursive booleanTRUE if using WITH RECURSIVE and FALSE if using WITH
return $thisThe query object itself
public function withQuery($query, $alias, $recursive = false)
{
$this->withQueries[] = ['query' => $query, 'alias' => $alias, 'recursive' => $recursive];
return $this;
}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4