Îðëà
Îáëàñòè
Êîìïàíèé
Ïîëüçîâàòåëè
Ãàëåðåÿ
Ôèêñèðîâàííûå íîâîñòè
Îðëà
Îòçûâû î ôèðìàõ
Òàðèôû
Ïîëüçîâàòåëè
Îáëàñòè
Áàíêîìàòû
Òîðãîâûå òî÷êè
Äîñêà îáúÿâëåíèé
Êóðñû âàëþò
Ñêèäêè
îðãàíèçàöèè Îðëà
îðãàíèçàöèè îáëàñòè
òîâàðû
ñàéòû
ñàéòû Îðåë
Äàííûå
Ðàçäåëû
Ïîèñê
Ïîèñê çàïðîñû
Ñòàòèñòèêà
Ïîêàçû êàòàëîãà îðãàíèçàöèé
Ñòàòèñòèêà êëèåíòû
Ïîëüçîâàòåëè
Ñàéòû
Óïðàâëåíèå ñàéòîì
Àíêåòà
Àïòåêè
Àôèøà
Àôèøà íîâàÿ
Áàííåðû
Áèçíåñ >
Âèêòîðèíà
Ãîëîñîâàíèå
Ãîñòü íà ñàéòå
Èñòîðèè
Êàëåíäàðü ñîáûòèé
Êàòàëîãè >
Êîíêóðñ êðàñîòû
Êîíêóðñ àóäèî
Êîíñóëüòàöèè
Ìåíþ
Íîâîå íà ñàéòå
Íîâîñòè >
Îðãàíèçàöèè >
Ïðîãðàììà ÒÂ
Ïóáëèêàöèè
Ðàçäåëû ñàéòà
Ðàññûëêà
Ðåñòîðàíû
Ñåêðåò ôèðìû >
Ñåðâèñû >
Ññûëêè
Òåñòû
Ôàéëîâûé ìåíåäæåð
Ôîðóì
Ôîòîãàëåðåÿ
Îáðàòíàÿ ñâÿçü
Íåäâèæèìîñòü
Íîâûé ãîä
Òåêñòû
Ïîëüçîâàòåëè
Þðèäè÷åñêèé ðåéòèíã
Îòçûâû íà òîâàðû
Áàí ïîëüçîâàòåëåé
Æàëîáû
Íîâûå òåñòû
Êîðîíàâèðóñ
Ôàéëîâûé ìåíåäæåð
Èìÿ ôàéëà
QueryBuilder.php
Ñîäåðæèìîå
<?php namespace app\core\models; use app\core\helpers\ArrayHelper; class QueryBuilder { /** * Выборка по таблицам * @var array */ private $_select = []; /** * Таблица из которой делаем выборку * @var string */ private $_tableName; /** * �айденные �лементы * @var array */ private $_items = []; /** * Е�ли передано название кла��а в �ту переменную * То мы заполним данные из метода one() или выполним "заливку" ма��ива из all() * @var null|string */ private $_modelClass; /** * Е�ли вы не передадите PDO объект дл� выборки, то выборки не будет. * @var \PDO */ private $_pdo; private $_relations = []; /** * ['AND|OR', $attribute, $condition, $value] * @var array */ private $_where = []; /** * Сколько запи�ей пропу�тить. * @var */ private $_offset; /** * Сколько запи�ей выводить. * @var */ private $_limit; /** * Сортировка * @var array */ private $_orderBy = []; /** * Группировка * @var array */ private $_groupBy = []; /** * true - Выводить только одну запи�ь, false - выводить в�е запи�и * @var bool */ private $_one = false; public function __construct($modelClass = null) { $this->_modelClass = $modelClass; $this->_pdo = \App::$pdo; return $this; } public static function updateById($tableName, $id, array $values) { if (empty($values)) { return false; } $placeholders = []; $updateSet = []; foreach ($values as $key => $value) { $updateSet[] = '`' . $key . '` = :value_' . $key; $placeholders[':value_' . $key] = $value; } $sql = ' UPDATE `'. $tableName .'` SET ' . implode(', ', $updateSet) . ' WHERE id = ' . (int) $id . ' '; return \App::$command ->createCommand($sql) ->bindValues($placeholders) ->query(); } public static function insert($table, $values) { $keys = array_keys($values); $keysPlaceholders = []; foreach ($keys as $key) { $keysPlaceholders[] = ':' . $key; } $sql = ' INSERT INTO `'. $table . '` (' . implode(',', $keys) . ') VALUES('. implode(',', $keysPlaceholders) .') '; $command = \App::$command ->createCommand($sql); foreach ($values as $key => $value) { $command->bindValue(':' . $key, $value); } if ($command->query()) { return $command->lastInsertId(); } return 0; } public static function deleteById($table, $id) { $sql = " DELETE FROM `{$table}` WHERE id = :id "; return \App::$command ->createCommand($sql) ->bindValue(':id', $id) ->query(); } /** * Перечи�ление ма��ива SELECT, дл� выборки из таблицы * Сюда можно передавать не только данные но и callback функции, которые будут преобразованы в значени�. * Пример: * ```php * $model->select([ * 'foo', * function() use ($user) { * if ($user->isGuest) { * return 'name_guest'; * } else { * return 'name_full; * } * } * ]) * ``` * @param array $select * @return $this */ public function select(array $select = ['*']) { foreach ($select as $item) { $this->addSelect($item); } return $this; } /** * Добавление какого-то одного пол� в SELECT * @param $select - �трока или callback - функци� * @return $this */ public function addSelect($select) { if (is_string($select) == false && is_callable($select)) { $select = call_user_func($select); } $this->_select[] = $select; return $this; } /** * Из какой таблицы делать выборку данных. * @param $table * @return $this; */ public function from($table) { $this->_tableName = $table; return $this; } /** * Функци�-хелпер дл� добавлени� у�лови� пои�ка WHERE по таблицам. * И�пользщуйте вме�то �той �той функции функции: * where, orWhere, andWhere. * * @param $type - тип при�оединени�. OR или AND * @param $attribute - поле фильтрации, например foo * @param $condition - у�ловие, по которому делаем выборку, например = > < * @param $value - значение дл� пои�ка. Может быть чи�лом, �трокой или функцией. */ private function addWhere($type, $attribute, $condition, $value) { if (is_callable($value)) { $value = call_user_func($value); } $this->_where[] = [$type, $attribute, $condition, $value]; } /** * Функци� добавл�ет новое у�ловие к таблице. * @param $attribute - поле, по которому ищем * @param $condition - у�ловие пои�ка, > < = !=... * @param $value - значение, может быть �трокой, чи�лом или функцией * @return $this */ public function andWhere($attribute, $condition, $value) { $this->addWhere('AND', $attribute, $condition, $value); return $this; } /** * Функци� добавл�ет новое у�ловие � при�оединением к предыдущему у�ловию по типу OR * @param $attribute * @param $condition * @param $value * @return $this */ public function orWhere($attribute, $condition, $value) { $this->addWhere('OR', $attribute, $condition, $value); return $this; } /** * Функци� добавл�ет у�ловие Where к запро�у. * ``php * $model->where([ * 'foo' => 'bar', * 'foo2' => function() { * return 'bar2'; * }, * ['>', 'foo3', 'bar'], * ['like', 'foo3', '%bar3%'] * ]); * ``` * @param array $andWhereCondition * @throws \Exception * @return $this */ public function where(array $andWhereCondition) { foreach ($andWhereCondition as $key => $value) { // е�ли у�ловие �вл�ет�� ма��ивом, то в пером индек�е // будет у�ловие выборки > < = != like и так далее if (is_array($value) && is_int($key)) { if (count($value) != 3) { throw new \Exception("Количе�тво параметров в WHERE передано неверно."); } // е�ли третий параметр �вл�ет�� callback фунцией, // то выполн�ем �ту функцию, чтобы получить значение if (is_callable($value[2])) { $value[2] = call_user_func($value[2]); } $this->andWhere($value[1], $value[0], $value[2]); } else { // е�ли $key не �вл�ет�� ма��ивом, в �том �лучае // поле было key => value �вл�ет�� ма��ивом if (is_callable($value)) { $value = call_user_func($value); } $this->andWhere($key, '=', $value); } } return $this; } /** * Группировка * @param array $group * @return $this */ public function groupBy(array $group) { foreach ($group as $item) { $this->addGroupBy($item); } return $this; } /** * Функци� добавл�ет еще один вариант группировки * @param $field * @return $this */ public function addGroupBy($field) { $this->_groupBy[] = $field; return $this; } /** * Сортировка * ```php * $model->orderBy([ * 'id' => SORT_DESC, * 'name' => SORT_ASC * ]); * ``` * @param array $orderBy * @return $this */ public function orderBy(array $orderBy) { foreach ($orderBy as $field => $sortType) { $this->addOrderBy($field, $sortType); } return $this; } /** * Функци� добавл�ет �ортировку к запро�у * @param $field - поле, по которому �ортируем. * @param $sortType * @return $this */ public function addOrderBy($field, $sortType) { if ($sortType != SORT_ASC && $sortType != SORT_DESC) { return $this; } $this->_orderBy[] = [ 'field' => $field, 'sortType' => $sortType ]; return $this; } /** * Сколько запи�ей пропу�тить * @param $offset * @return $this */ public function offset($offset) { $this->_offset = $offset; return $this; } /** * Сколько в�его запи�ей выве�ти. * @param $limit * @return $this */ public function limit($limit) { $this->_limit = $limit; return $this; } /** * Добавление новых �в�зей. * @param array $relations * @return $this * @throws \Exception */ public function with(array $relations) { if ($this->_modelClass == null) { throw new \Exception('Дл� и�пользовани� метода необходимо передать модель таблицы через ActiveRecord'); } $this->_relations = $relations; return $this; } /** * Функци� добавл�ет \PDO дл� запро�ов * @param \PDO $pdo * @return $this */ public function setDb(\PDO $pdo) { $this->_pdo = &$pdo; return $this; } /** * @param $tableName * @param array $select * @param array $where * @param array $group * @param array $order * @param null $offset * @param null $limit * * Первый �лемент ма��ива будет �ам sql запро�, * второй �лемент ма��ива будет array дл� execute pdo * @return array */ public static function generateSqlCode($tableName, array $select, array $where, array $group, array $order, $offset = null, $limit = null) { $whereType = 0; $whereAttribute = 1; $whereCondition = 2; $whereValue = 3; if (count($select) == 0) { $select = ['*']; } $sql = ' SELECT ' . implode(',', $select) . ' FROM `' . $tableName . '` '; $executeConditionParams = []; $whereString = ''; if (count($where) > 0) { $whereString = ' WHERE '; $i = 0; foreach ($where as $whereItem) { $whereConditionString = null; // ['AND|OR', $attribute, $condition, $value] if ($whereItem[$whereCondition] == 'LIKE' || $whereItem[$whereCondition] == 'like') { $whereConditionString = ' ' . $whereItem[$whereAttribute] . ' LIKE "%' . str_replace(['"', "'", "SELECT", "INSERT", "UPDATE", "DELETE", "DROP"],'', trim(htmlspecialchars($whereItem[$whereValue]))) . '%"'; } else { // проверка на у�ловие вида IN // в QueryBuilder �то у�ловие выгл�дит �ледующим образом // ->where([ // 'field' => [1, 2, 3] // ]); if (is_array($whereItem[$whereValue])) { $whereConditionString = ' ' . $whereItem[$whereAttribute] .' IN (' . implode(',', $whereItem[$whereValue]) . ')'; } else { if ($whereItem[$whereValue] instanceof Expression) { // // у�ловие �вл�ет�� каким-то SQL выражением // в �том �лучае не нужно обрабатывать его �ред�твами PHP $whereConditionString = ' ' . $whereItem[$whereAttribute] . ' ' . $whereItem[$whereCondition] . ' ' . $whereItem[$whereValue]->getValue(); } else { // зде�ь нет какого-либо у�лови�, зде�ь // мы про�то подготавливаем шаблоны вида // key = value, где = одно из у�ловий $whereConditionString = ' ' . $whereItem[$whereAttribute] . ' ' . $whereItem[$whereCondition] . ' :' . $whereItem[$whereAttribute]; $executeConditionParams[':' . $whereItem[$whereAttribute]] = $whereItem[$whereValue]; } } } if ($i == 0) { $whereString .= $whereConditionString; } else { $whereString .= ' ' . $whereItem[$whereType] . $whereConditionString; } $i = $i + 1; } } $sql .= $whereString; // группировка if (count($group) > 0) { $sql .= ' GROUP BY ' . implode(',', $group); } // �ортировка if (count($order) > 0) { $orderArray = []; foreach ($order as $orderItem) { // field, sortType $sortType = $orderItem['sortType'] == SORT_DESC ? 'DESC' : 'ASC'; $orderArray[] = $orderItem['field'] . ' ' . $sortType; } $sql .= ' ORDER BY ' . implode(',', $orderArray); } if ($offset !== null && $limit !== null) { $sql .= ' LIMIT ' . (int)$offset . ',' . (int)$limit; } else { if ($limit > 0) { $sql .= ' LIMIT ' . (int)$limit; } } return [ $sql, $executeConditionParams ]; } /** * Формируем SQL запро� к базе данных */ public function query() { $modelClass = null; if ($this->_modelClass != null) { $modelClass = new $this->_modelClass(); } if ($this->_pdo instanceof \PDO == false) { throw new \Exception("�евозможно выполнить запро�. PDO объект не найден"); } $sqlArray = static::generateSqlCode( $this->_tableName, $this->_select, $this->_where, $this->_groupBy, $this->_orderBy, $this->_offset, $this->_limit ); $sth = $this->_pdo->prepare($sqlArray[0]); $sth->execute($sqlArray[1]); $this->_items = $sth->fetchAll(); // е�ли был передан кла�� из $activeRecord // то мы должны заполнить ма��ив $items �тим кла��ом и потом вернуть их if ($this->_modelClass != null) { foreach ($this->_items as $key => $item) { $model = new $this->_modelClass(); foreach ($item as $key2 => $value) { $model->{$key2} = $value; } $model->resetModifiedAttributes(); $this->_items[$key] = $model; } } if (count($this->_items) > 0 && count($this->_relations) > 0 && $modelClass != null) { foreach ($this->_relations as $key => $relation) { /** @var RelationAttribute */ if (is_callable($relation)) { $relationClass = $modelClass->{'get' . ucfirst($key)}(); $relationClass->select(call_user_func($relation)); $relationName = $key; } else { $relationClass = $modelClass->{'get' . ucfirst($relation)}(); $relationName = $relation; } // Подробнее о переменной $relationName // когда мы делаем �в�зь через with(), то указываем название �в�зи // переменна� $relationName как раз и �одержит �то название. // к примеру е�ть вот такой код: // // ->with([ // 'user' // ]) // // то по�ле прохода foreach выше в переменной $relationName // будет название user, ну или то, что в нее под�тавили. // // Зде�ь будет �в�зь вида 'id' из родитель�кой таблицы // в дочернию таблицу �в�зи. // пример ['id' => 'user_id'] $where = $relationClass->getCondition(); $whereConditionKey = array_keys($where)[0]; $values = []; foreach ($this->_items as $item) { $values[] = $item->{$whereConditionKey}; } // �оздаем �кземпл�р �того кла��а, // чтобы потом заполнить ма��ив $this->_items по полю $relationName $thisClass = new self($relationClass->getTargetClassName()); $thisClass->from($relationClass->getTableName()) ->select($relationClass->getSelect()) ->setDb($this->_pdo) ->where([ $where[$whereConditionKey] => $values ]); $items = $thisClass->all(); foreach ($this->_items as $keyItem => $item) { if ($relationClass->getRelationType() == RelationAttribute::RELATION_TYPE_HAS_ONE) { $this->_items[$keyItem]->{$relationName} = null; } else { $this->_items[$keyItem]->{$relationName} = []; } foreach ($items as $keyRelation => $relationItem) { if ($relationItem->$where[$whereConditionKey] == $item->$whereConditionKey) { $this->_items[$keyItem]->{$relationName}[] = $relationItem; } } if (isset($this->_items[$keyItem]->{$relationName}) && count($this->_items[$keyItem]->{$relationName}) > 0) { if ($relationClass->getRelationType() == RelationAttribute::RELATION_TYPE_HAS_ONE) { $this->_items[$keyItem]->{$relationName} = $this->_items[$keyItem]->{$relationName}[0]; } } } } } if ($this->_one == true) { if (count($this->_items) > 0) { $this->_items = $this->_items[0]; } } return $this->_items; } public function one() { $this->_one = true; return $this->query(); } public function all() { $this->_one; return $this->query(); } }
/app/core/models/
Èìÿ
Äàòà
Ðàçìåð
..
2019-02-12
validators
2026-05-25
ActiveRecord.php
2023-09-07
10 êá.
ActiveRecord.php~
2016-12-23
10 êá.
BaseModel.php
2016-12-22
167 áàéò
Command.php
2016-12-22
199 áàéò
Expression.php
2016-12-22
329 áàéò
Form.php
2016-12-22
6 êá.
Mail.php
2016-12-22
762 áàéò
MySQLCommand.php
2019-01-31
1 êá.
NoInjection.php
2019-01-30
987 áàéò
QueryBuilder.php
2020-03-10
20 êá.
RelationAttribute.php
2016-12-22
5 êá.
SqlModel.php
2016-11-24
98 áàéò
WhereConditionHelper.php
2019-01-30
813 áàéò
/app/core/models
Çàãðóçèòü ôàéëû
Ôàéë 1
Ôàéë 2
Ôàéë 3