- Небольшой класс для работы с БД ( PDO )
- Вступление
- Реализация метода query
- Моя реализация
- Применение
- В заключении
- Обработка результатов запросов
- Выполнение запросов, обработка результатов и получение данных
- Создаем класс для работы с базой данных в PHP
- Скелет класса PHP для работы с базой данных
- Пишем метод __construct();
- метод select();
Небольшой класс для работы с БД ( PDO )
Привет, Хабр! Очень много статей написано о PDO, но при этом очень мало реальных примеров. В этой статье я хочу представить свою версию класса для работы с базой данных (далее — БД). Эта статья будет полезна начинающим программистам, которые только осваивают эту технологию.
Внимание! Моё мнение может отличаться от вашего, поэтому хочу сразу сказать, что эта статья не есть истина в последней инстанции и реализация этого класса зависит от программиста и его предпочтений.
Вступление
Тут, я думаю, всё понятно, эти вещи можно не объяснять.
Далее большая часть пояснений будет содержаться в коде.
db = new PDO('mysql:host=' . $dbinfo['host'] . ';dbname=' . $dbinfo['dbname'], $dbinfo['login'], $dbinfo['password']); > > ?>
Прекрасно, мы подключились к БД. Теперь нам нужно создать метод, который позволит совершать SQL запросы.
db = new PDO('mysql:host=' . $dbinfo['host'] . ';dbname=' . $dbinfo['dbname'], $dbinfo['login'], $dbinfo['password']); > // Операции над БД public function query($sql, $params = []) < >> ?>
Реализация метода query
Мы готовы к реализации этого метода, но у нас возникает вопрос:
«Что за параметры он принимает и как он должен их использовать?»
Ответ на первый вопрос очевиден:
- $sql — переменная с текстом SQL запроса.
- $params — переменная с какими-то параметрами для запроса.
А что со вторым вопросом?
Всё так же просто, что бы ответить на этот вопрос, мы должны узнать, в каком виде нам подают эти параметры. А получаем мы их вот такими:
У незнающего человека возникает вопрос: «Что за двоеточие?» Я тут же отвечаю — такие запросы называются подготовленными и используются, дабы исключить возможность SQL инъекции.
Вернёмся к предыдущему вопросу и ответим на него:
Мы должны обойти массив $params и подставить значение в запрос.
Но сначала, мы должны подготовить запрос для подстановки этих значений. В итоге код будет выглядеть так:
db = new PDO('mysql:host=' . $dbinfo['host'] . ';dbname=' . $dbinfo['dbname'], $dbinfo['login'], $dbinfo['password']); > // Операции над БД public function query($sql, $params = []) < // Подготовка запроса $stmt = $this->db->prepare($sql); // Обход массива с параметрами // и подставление значений if ( !empty($params) ) < foreach ($params as $key =>$value) < $stmt->bindValue(":$key", $value); > > // Выполняем запрос $stmt->execute(); // Возвращаем ответ return $stmt->fetchAll(PDO::FETCH_ASSOC); > > ?>
Некоторые комментарии немного искажают истину, но при этом кардинально ничего не меняют
Мы имеем уже довольно мощный инструмент, использующий подготовленные запросы и требующий от разработчиков знание SQL, а не тонкостей класса. Но при этом, я бы зашил в этот класс типовые запросы, такие как:
- getAll() — двумерный массив, индексированный числами по порядку
- getRow() — одномерный массив, первую строку результата
Моя реализация
Эти методы могут быть реализованы по разному, но я представлю свою реализацию.
db = new PDO('mysql:host=' . $dbinfo['host'] . ';dbname=' . $dbinfo['dbname'], $dbinfo['login'], $dbinfo['password']); > // Операции над БД public function query($sql, $params = []) < // Подготовка запроса $stmt = $this->db->prepare($sql); // Обход массива с параметрами // и подставляем значения if ( !empty($params) ) < foreach ($params as $key =>$value) < $stmt->bindValue(":$key", $value); > > // Выполняя запрос $stmt->execute(); // Возвращаем ответ return $stmt->fetchAll(PDO::FETCH_ASSOC); > public function getAll($table, $sql = '', $params = []) < return $this->query("SELECT * FROM $table" . $sql, $params); > public function getRow($table, $sql = '', $params = []) < $result = $this->query("SELECT * FROM $table" . $sql, $params); return $result[0]; > > ?>
Здесь эти методы реализованы, возможно не лучшим образом, но реализованы.
Так же сюда можно добавить ещё функции, упрощающие жизнь, но лично мне этого с головой хватает.
Можно добавить следующие методы:
- getOne() — возвращает первый элемент первой строки результата
- getCol() — возвращает 1 колонку таблицы
- и т.д.
Применение
Мы написали наш класс. Теперь нам нужно протестировать его в реальном «бою».
Давайте попробуем. Для начала нам нужно создать любую таблицу в БД, допустим это будет таблица posts. Добавим туда пару записей и попробуем вывести их с помощью нашего класса.
Далее я не буду приводить код класса DB . Подразумевается, что этот класс либо написан выше, либо подключается к этому скрипту.
Так как ранее я не показал файл dbinfo.php — сейчас я приведу код этого конфигурационного файла.
'127.0.0.1', 'dbname' => 'test', 'login' => 'root', 'password' => '' ]; ?>
Это понятно и не требует объяснения, идём дальше. Теперь, давайте попросим БД test вернуть нам значение всех постов при помощи нашего класса.
// Создаём объект $db = new DB; // Получаем и выводим данные echo ""; print_r($db->getAll('posts')); ?>
На выходе мы имеем следующее:
Отлично, а теперь давайте выведем только первый пост.
// Создаём объект $db = new DB; // Получаем и выводим данные echo ""; print_r($db->getRow('posts')); ?>
Прекрасно. Ну и в конце добавим запись и выведем данные до и после.
// Создаём объект $db = new DB; // Получаем и выводим данные echo "До
"; print_r($db->getAll('posts')); echo "
После
"; $params = [ 'title' => 'Заголовок через PHP', 'author' => 'Автор через PHP' ]; $db->query('INSERT INTO `posts` ( title, author ) VALUES ( :title, :author )', $params); print_r($db->getAll('posts')); ?>
Мы получили то, что хотели и убедились в том, что этот класс рабочий.
В заключении
В конце статьи я хочу повториться и сказать, что моя реализация не идеальна, но всё таки данный класс работает и выполняет свою главную функцию - работает с базой данных. Надеюсь для вас эта статья была полезной
Ссылка на github: class DB
Обработка результатов запросов
Выполнение запросов, обработка результатов и получение данных
Описываем нужный SQL-запрос и помещаем его в переменной $sql .
Затем выполняем запрос к базе данных с помощью метода query объекта mysqli.
Если ошибок нет — получим объект mysqli_result , который сохраняется в переменной $result .
Если же в SQL-запросе присутствуют ошибки — метод query вернет FALSE ,
тогда с помощью оператора throw генерируем исключение, которое обрабатываем с помощью Exception .
// устанавливаем соединение с базой данных newDB (создаем экземпляр класса new mysqli())
$conn = new mysqli($servername, $username, $password, $dbname);
// SQL-запрос
$sql = "SELECT * FROM users ";
// запрос к базе данных
$result = $conn->query($sql);
if ($result === FALSE) <
throw new \Exception('Ошибка в SQL-запросе!');
>else <
echo "Выполнено:
";
>
Получение данных одной строки в виде ассоциативного массива:
Получение данных одной строки в виде индексированного массива:
Получение данных одной строки в виде объекта:
$entries = array();
while ($entry = $result->fetch_object()) <
$entries[] = $entry;
>
Получение всех строк в виде ассоциативного массива:
Если результат не содержит количество результатов выборки - num_rows , выведем: "Нет результатов".
Выражение $result->$num_rows - получает число рядов в результирующей выборке
if (!$result->num_rows) <
echo "Нет результатов:
";
>
Описываем нужный SQL-запрос и помещаем его в переменной $sql .
Затем выполняем запрос к базе данных с помощью функции mysqli_query($conn, $sql) и помещаем результат в переменную $result
// устанавливаем соединение с базой данных newDB
$conn = mysqli_connect($servername, $username, $password, $dbname);
// SQL-запрос
$sql = "SELECT * FROM users";
// запрос к базе данных
$result = mysqli_query($conn, $sql);
Эта функция возвращает одну запись выборки в виде индексированного массива:
Эта функция возвращает одну запись выборки в виде ассоциативного массива:
Эта функция в зависимости от параметров может вернуть либо индексированный массив,
либо ассоциативный массив, либо массив, содержащий и индексы и строковые ключи:
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
Получение всего результата .
Эта функция возвращает двухмерный массив, содержащий все записи:
$row = mysqli_fetch_all($result, MYSQLI_ASSOC);
Если запрос к базе данных - выполнен, тогда выведем сообщение "Выполнено".
В противном случае выведем сообщение "Ошибка" и выведем информацию об ошибке mysqli_error($conn) :
if(mysqli_query($conn, $sql)) <
echo "Выполнено";
>else <
echo "Ошибка:
" . mysqli_error($conn);
>
Выбираем данные из таблицы workers (Стиль ООП).
$servername = "localhost" ;
$username = "root" ;
$password = "" ;
$dbname = "newDB" ;
// Устанавливаем соединение с сервером MySQL:
$conn = new mysqli ( $servername , $username , $password , $dbname );
// Проверка соединения:
if ( $conn -> connect_error ) die ( "Не удалось подключиться: " . $conn -> connect_error );
>
echo "Соединение успешно установлено" ;
//1. Выбрать значения всех полей из таблицы workers:
// $sql = "SELECT * FROM workers ";
//2. Выбрать значения всех полей из таблицы workers, где >
// $sql = "SELECT * FROM workers WHERE >
//3. Выбрать значение поля id из таблицы workers, где значение поля name = 'Иван':
// $sql = "SELECT id FROM workers WHERE name = 'Иван'";
//4. Выбрать значение поля name из таблицы workers, где id > 5:
// $sql ;
//5. Выбрать значения всех полей из таблицы workers,
// где значение поля name = 'Сидор' И значение поля age > 30:
// $sql ;
//6. Иногда нужно указать много значений:
$sql = "SELECT name FROM workers WHERE AND AND >;
// Выполнение запроса
$result = $conn -> query ( $sql );
// Проверка выполнения запросов
if ( $result === FALSE ) throw new \ Exception ( 'Ошибка в SQL-запросе!' );
> else <
echo "Выполнено:
" ;
>
// получить все строки в виде ассоциативного массива
$entries = $result -> fetch_all ( MYSQLI_ASSOC );
// num_rows содержит количество результатов выборки
if (! $result -> num_rows ) echo "Нет результатов:
" ;
>
// закрываем соединение
$conn -> close ();
?>
Создаем класс для работы с базой данных в PHP
Замечание: данный класс не является эталонным, на который стоит равняться. Цель данного урока показать, как можно все удобно сгруппировать для комфорта создания CMS в будущем.
Скелет класса PHP для работы с базой данных
Прежде чем начать писать класс для работы с базой данных в PHP, мы сначала набросаем его скелет, кстати имя нашего класса будет DBClass.
Во-первых, нам понадобиться два метода:
для того, чтобы соединится с базой;
Онлайн курс «PHP-разработчик»
Изучите курс и создайте полноценный проект — облачное хранилище файлов
С нуля освоите язык программирования PHP, структурируете имеющиеся знания, а эксперты помогут разобраться с трудными для понимания темами, попрактикуетесь на реальных задачах. Напишете первый проект для портфолио.
Во-вторых, в скелет класса войдет группа методов дляредактирование определенных таблиц базы данных. Например, вставка, удаление, выборка – insert, delete, select соответственно. Операции типа редактирование и т.п. будет вам как домашнее задание. Напишите сами, тем самым дополнив базу данных новыми полезными компонентами, то есть методами.
Схематический скелет класса DBClass:
function__construct(); (метод, который вызывается автоматически, при создании класса)
Пишем метод __construct();
В этот метод извне мы будет передавать 4 параметра: хост, имя пользователя, пароль, имя базы данных. Потом присвоим эти переменные аналогичным классовым переменным. И конечно, же вызовем метод открытия соединения сMySQL.
метод select();
Цель метода состоит в возвращении массива значений выбранных полей в запросе. С полученным массивом в будущем будет намного проще работать. Разберем словесно алгоритм работы метода.
Объявляем переменную $fetched как массив, в котором будет храниться значения выбранных полей в запросе.
Формируем запрос ($sql) в MySQL и отправляем его mysql_query($sql)
Начало цикла $i
Далее у нас идет цикл for, в котором мы перебираем выбранные из MySQL строки по очереди. Количество строк узнаем при помощи функции mysql_num_rows()
В цикле мы по очереди извлекаем результирующий ряд (строку) как ассоциативный массив, с которого сразу же возвращаем все ключи массива в переменную $key
Считаем количество элементов массива $key ($numKeys = count($key);)
Начало цикла $x
Далее идет цикл, в котором мы формируем конечный массив значений выбранных полей в запросе.
Конец цикла $x
Конец цикла $i
Далее else(елсами) возвращаем при неудаче false к соответствующим ифам (if).