<MyRusakov.ru />

Фреймворк Yii 2.0 с нуля. Пример создания сайта

Фреймворк Yii 2.0 с нуля. Пример создания сайта

Видеокурс "Фреймворк Yii 2.0 с нуля. Пример создания сайта" обучит Вас созданию профессиональных сайтов с использованием фреймворка Yii. В курсе есть 2 раздела: теоретический и практический. В теоретическом разделе будут разобраны возможности фреймворка Yii с примерами их использования, а в практической части будет создан сайт Blog.MyRusakov.ru с помощью полученных знаний из теоретического раздела.

Так же почти ко всем урокам идут упражнения для закрепления материала из урока на практике.

После прохождения курса Вы без труда сможете создавать любые сайты с использованием фреймворка Yii, причём делать это будете быстро и качественно.

Подробнее
Подписка

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Каким движком Вы предпочитаете пользоваться?

Класс для работы с базой данных

Класс для работы с базой данных

Недавно я заметил, что в Интернете можно найти огромное количество PHP-классов для работы с базой данных. Как обычно, они всегда щеголяют своей функциональностью и количеством возможностей. Я решил тоже написать свой класс для работы с базой данных, но пошёл по другому пути. Я хотел сделать такой класс, чтобы в нём был тот необходимый минимум функционала, который только и требуется. Всё остальное - это уже непонятные навороты, которые использовать, как минимум, небезопасно.

Привожу свой прокомментированный класс для работы с базой данных:

<?php
class DataBase {

  private static $db = null; // Единственный экземпляр класса, чтобы не создавать множество подключений
  private $mysqli; // Идентификатор соединения
  private $sym_query = "{?}"; // "Символ значения в запросе"

  /* Получение экземпляра класса. Если он уже существует, то возвращается, если его не было, то создаётся и возвращается (паттерн Singleton) */
  public static function getDB() {
    if (self::$db == null) self::$db = new DataBase();
    return self::$db;
  }

  /* private-конструктор, подключающийся к базе данных, устанавливающий локаль и кодировку соединения */
  private function __construct() {
    $this->mysqli = new mysqli("localhost", "root", "", "my_db");
    $this->mysqli->query("SET lc_time_names = 'ru_RU'");
    $this->mysqli->query("SET NAMES 'utf8'");
  }

  /* Вспомогательный метод, который заменяет "символ значения в запросе" на конкретное значение, которое проходит через "функции безопасности" */
  private function getQuery($query, $params) {
    if ($params) {
      for ($i = 0; $i < count($params); $i++) {
        $pos = strpos($query, $this->sym_query);
        $arg = "'".$this->mysqli->real_escape_string($params[$i])."'";
        $query = substr_replace($query, $arg, $pos, strlen($this->sym_query));
    }
    }
    return $query;
  }

  /* SELECT-метод, возвращающий таблицу результатов */
  public function select($query, $params = false) {
    $result_set = $this->mysqli->query($this->getQuery($query, $params));
    if (!$result_set) return false;
    return $this->resultSetToArray($result_set);
  }

  /* SELECT-метод, возвращающий одну строку с результатом */
  public function selectRow($query, $params = false) {
    $result_set = $this->mysqli->query($this->getQuery($query, $params));
    if ($result_set->num_rows != 1) return false;
    else return $result_set->fetch_assoc();
  }

  /* SELECT-метод, возвращающий значение из конкретной ячейки */
  public function selectCell($query, $params = false) {
    $result_set = $this->mysqli->query($this->getQuery($query, $params));
    if ((!$result_set) || ($result_set->num_rows != 1)) return false;
    else {
      $arr = array_values($result_set->fetch_assoc());
      return $arr[0];
    }
  }

  /* НЕ-SELECT методы (INSERT, UPDATE, DELETE). Если запрос INSERT, то возвращается id последней вставленной записи */
  public function query($query, $params = false) {
    $success = $this->mysqli->query($this->getQuery($query, $params));
    if ($success) {
      if ($this->mysqli->insert_id === 0) return true;
      else return $this->mysqli->insert_id;
    }
    else return false;
  }

  /* Преобразование result_set в двумерный массив */
  private function resultSetToArray($result_set) {
    $array = array();
    while (($row = $result_set->fetch_assoc()) != false) {
      $array[] = $row;
    }
    return $array;
  }

  /* При уничтожении объекта закрывается соединение с базой данных */
  public function __destruct() {
    if ($this->mysqli) $this->mysqli->close();
  }
}
?>

Как видите, нет ничего лишнего, только всё самое необходимое. Теперь разберём PHP-код, который использует данный класс:

<?php
  $db = DataBase::getDB(); // Создаём объект базы данных
  $query = "SELECT * FROM `users` WHERE `id` > {?} AND `online` = {?}";
  $table = $db->select($query, array(10, 1)); // Запрос явно должен вывести таблицу, поэтому вызываем метод select()
  $query = "SELECT `login` FROM `users` WHERE `email` = {?}";
  $login = $db->selectCell($query, array("test@mail.ru"));// Запрос должен вывести конкретную ячейку, поэтому вызываем метод selectCell()
?>

Теперь Вы понимаете, что для удобной и безопасной работой с базой данных вовсе не требуется библиотека из 100 классов. Всё необходимое имеется, и данный класс без проблем обработает любой запрос. Единственное, что я рекомендую - это настройки вынести в отдельный класс. То есть адрес хоста, имя пользователя, пароль, название базы данных, кодировку, локаль и "символ значения" вынести в отдельный класс, откуда их считывать.

Вот такой незамысловатый класс для работы с базой данных я использую в своих проектах.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (20):

sync.o sync.o 22.02.2013 11:40:12

Интересный метод getQuery(), напоминает параметризованные запросы prepare(), bind_param()... Как по вашему, стоит ли заморачиваться с ними или для безопасности вполне хватит вашего подхода для подстановки значений в запрос?

Ответить

Admin Admin 22.02.2013 20:17:27

Лично я их не использую и особого смысла не вижу.

Ответить

malina95 malina95 25.06.2013 02:10:34

Михаил, а можете написать пример изменёной функции getQuery так, чтобы ставить не {?} а что-то типа :i, :s, :? тоесть i это число, s это строка, ? это любое значение, как сделать такое распределение, напишите пожалуйста, если вдруг тут не захотите писать, то напишите мне в ответ "Пишите на форум и я отвечу и помогу с примером", хорошо?

Ответить

Scaletta Scaletta 14.07.2013 16:50:37

Михаил, возникла проблема... Все методы работают кроме select и selectRow. Не знаю в чем проблема, никаких ошибок не выводит но и то, что нужно тоже :( Я в отчаянии...

Ответить

Admin Admin 14.07.2013 17:08:30

Скорее всего, ошибка в Вашем запросе. Используйте этот метод для поиска ошибок: http://myrusakov.ru/php-finderror.html и для поиска ошибки в SQL: http://myrusakov.ru/sql-finderror.html

Ответить

Scaletta Scaletta 14.07.2013 17:21:31

Ок, задам вопрос по другому. Как правильно вывести все данные из таблицы в БД используя метод select в вашем классе? $query = "SELECT * FROM `users`"; $db->select($query) - не прокатывает, возвращает Array если вывести print-ом.

Ответить

Admin Admin 14.07.2013 21:38:14

Он Array и должен возвращать. Это же массив данных.

Ответить

tanysha86 tanysha86 15.10.2013 23:46:09

Михаил, спасибо БОЛЬШОЕ Вам за это курс, подскажите, пожалуста, нет ли в отправке формы в БД каких-либо особенностей при отправке значений радиокнопок? У меня есть форма отзыва о компании, в которой есть 2 текстовых поля и 2 поля с радиокнопками. Значения полей с текстом в БД попадает, а выбранное значение радиокнопок-нет. просто пустая ячейка. Хотя через echo на странице оно выводиться?

Ответить

Admin Admin 16.10.2013 11:43:10

Никаких особенностей нет, надо просто искать ошибку: http://myrusakov.ru/php-finderror.html

Ответить

tuttifrutti tuttifrutti 07.02.2014 01:12:31

Спасибо за класс, удобно. Прошу показать пример работы с insert и update

Ответить

Avery Avery 23.02.2014 16:24:02

Мне больше вот этот нравится, не знаю, дает он 100% защиту от sql инъекция, но хотя бы какая то. http://habrahabr.ru/post/165069/

Ответить

kruty kruty 09.03.2014 20:28:26

Дякую за посилання.. дуже зручно і безпечно.

Ответить

mikelyo mikelyo 05.06.2014 16:20:01

Не получается подключиться к базе данных. Куда класть этот файл класса БД?

Ответить

tikkiwiki tikkiwiki 05.06.2014 16:33:07

В папку положите корневую.

Ответить

mikelyo mikelyo 05.06.2014 17:34:42

Так и сделал. Все пхп туда положил. Даже пароль от базы данных пишу нарочно неправильный - ошибки не выдает.

Ответить

mikelyo mikelyo 05.06.2014 21:29:59

Сделал! Сделал! Оказывается в файле класса БД не надо было прописывать данные БД (логин пароль и пр.)!

Ответить

McLotos McLotos 17.07.2014 10:01:45

А я его чуть-чуть под себя переделал. Убрал конструктор, вместо него добавил метод set_parameters(). Это позволило задавать параметры объекта при создании нового экземпляра. Т.е. реализовано это так public $server; public $host; public $port; public $user; public $pass; public $base; public function set_parameters() { $this->mysqli = new mysqli($this->host.':'.$this->port,$this->user,$this->pass,$this->base); $this->mysqli->query("SET lc_time_names = 'ru_RU'"); $this->mysqli->query("SET NAMES 'utf8'"); } Теперь когда мне нужно создать новый экземпляр класса с другими параметрами, я делаю так $db = new dBase; $db -> server = SQL_SERVER; $db -> host = SQL_HOST; $db -> port = SQL_PORT; $db -> user = SQL_USER; $db -> pass = SQL_PASS; $db -> base = SQL_BASE; $db -> set_parameters(); Таким образом класс стал более гибким, ну т.е. мне не нужно каждый раз править файл класса чтобы подключиться к новому серверу, и появилась возможность переключаться между серверами "на лету"

Ответить

Icetalis Icetalis 05.11.2015 17:23:13

Добрый день. Не могу понять, а по чему в методах массиву $params присваевается значиние false?

Ответить

Ibragim_09_1986 Ibragim_09_1986 27.04.2016 09:55:44

Здравствуйте! В запрос msqli->query(объект) отправляется как параметр объект класса. Вопрос: как этот запрос вытаскивает из объекта сформированный запрос для баз данных msql? Пример Вашего кода: $result_set = $this->mysqli->query(AbstractSelect $select);

Ответить

shmel010201 shmel010201 24.06.2016 15:40:15

Добавить этот весь код надо в один файл? У меня database_class.php

Ответить

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.