Доступ к базе данных в PHP
Практическая часть использования PDO API для работы с базой данных.
Что?
Для соединения с базой данных MySQL имеется три разных API:
mysql
mysqli
– MySQL Improved (улучшенная)pdo
– PHP Data Objects (объекты данных PHP)
Традиционный API mysql
хорошо выполняет свою работу и получил широкое распространение благодаря тому, что делает процесс получения записей из базы данных очень простым. Например:
/* * Демонстрация старого способа работы с базой данных MySQL */ # Соединение mysql_connect('localhost', 'username', 'password') or die('Could not connect: ' . mysql_error()); # Выбор базы данных mysql_select_db('someDatabase') or die('Не могу выбрать базу данных'); # Выполнение запроса $query = "SELECT * from someTable"; $result = mysql_query($query) or die('Query failed: ' . mysql_error()); # Фильтрация строк и вывод нужной информации while ($row = mysql_fetch_object($result)) { echo $row->name; }
Да, приведенный пример очень прост. Но у него есть существенные недостатки:
- Устарел: хотя официально его не признают устаревшим, но для новых приложений и обучения лучше использовать другие API.
- Очистка: процесс очистки ввода пользователя от ненужного кода ложится на плечи разработчика.
- Гибкость: данный API не гибкий и работает только с базой данных MySQL. А если нужно перейти на другую?
PDO (PHP Data Objects) предоставляет более мощный инструмент для использования. Не нужно думать о драйвере базы данных, можно использовать подготовленные выражения, исключаются инъекции кода SQL.
Как?
На первый взгляд PDO API выглядит устрашающе. Не потому что он чрезмерно сложен, а потому что mysql
является очень простым! Нужно просто сделать несколько несложных действий.
Соединение
Вы уже знаете устаревший способ соединения с базой данной MySQL:
# Соединение mysql_connect('localhost', 'username', 'password') or die('Could not connect: ' . mysql_error());
При работе с PDO нужно создать новый экземпляр класса, указать драйвер, имя базы данных, имя пользователя и пароль:
$conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);
Ничего сложного.
Преимуществом данного подхода является простота изменения базы данных. Достаточно поменять имя источника данных. Нет зависимости от MySQL как при использовании функции mysql_connect
.
Ошибки
Но что если произойдет ошибка при соединении с базой данных? Обернем все в блок try/catch
:
try { $conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $e) { echo 'ERROR: ' . $e->getMessage(); }
Обратите внимание на то, что по умолчанию для PDO установлен режим работы с ошибками PDO::ERRMODE_SILENT
. Если все оставить без изменении, то придется вручную обрабатывать ошибки после выполнения запроса.
echo $conn->errorCode(); echo $conn->errorInfo();
При разработке лучше устанавливать режим PDO::ERRMODE_EXCEPTION
, в котором необработанные ошибки будут вызывать исключения и остановку скрипта.
Доступны следующие режимы работы с ошибками:
PDO::ERRMODE_SILENT
PDO::ERRMODE_WARNING
PDO::ERRMODE_EXCEPTION
Получаем данные
Итак, у нас есть соединение с базой данных и теперь нужно получить данные. Есть два способа решить поставленную задачу: query
и execute
. Рассмотрим оба.
Query
/* * Метод query */ $name = 'Joe'; # user-supplied data try { $conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $data = $conn->query('SELECT * FROM myTable WHERE name = ' . $conn->quote($name)); foreach($data as $row) { print_r($row); } } catch(PDOException $e) { echo 'ERROR: ' . $e->getMessage(); }
Хотя выше приведенный пример будет работать, нам нужно вручную очищать данные пользователя с помощью метода PDO::quote
. Данный метод эквивалентен функции mysql_real_escape_string
(в обоих случаях строка очищается и заключается в кавычки). В случаях, когда нужно построить запрос SQL с использованием пользовательских данных, лучше применять подготовленные выражения. То есть, если запрос SQL не зависит от ввода пользователя, метод query
будет отличным выбором, а результат можно обработать выражением foreach
.
Execute
/* * Метод execute */ $id = 5; try { $conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id'); $stmt->execute(array('id' => $id)); while($row = $stmt->fetch()) { print_r($row); } } catch(PDOException $e) { echo 'ERROR: ' . $e->getMessage(); }
В данном примере используется также метод prepare
для подготовки запроса, перед тем, как присоединить данные пользователя. В таком случае инъекция SQL теоретически невозможна, так как сами данные не вставляются в текст запроса SQL. Используется именованный параметр (:id
) для обозначения места.
Затем выполняется запрос с передачей массива, который содержит данные, которые следует использовать на месте именованного параметра.
$stmt->execute(array('id' => $id));
В качестве альтернативы можно использовать метод bindParam
:
$stmt->bindParam(':id', $id, PDO::PARAM_INT); $stmt->execute();
Обрабатываем данные
После вызова метода execute
есть несколько способов получить данные: массив (по умолчанию), объект и так далее. В выше приведенном примере используется режим по умолчанию: PDO::FETCH_ASSOC
. Его легко поменять, если нужно:
while($row = $stmt->fetch(PDO::FETCH_OBJ)) { print_r($row); }
Теперь результат будет в виде объекта. Доступны следующие опции:
- PDO::FETCH_ASSOC: Возвращает массив.
- PDO::FETCH_BOTH: Возвращает массив, проиндексированный по колонке с именем.
- PDO::FETCH_BOUND: Возвращает TRUE и назначает значение столбцов в наборе результата связанным переменным PHP.
- PDO::FETCH_CLASS: Возвращает новый экземпляр указанного класса.
- PDO::FETCH_OBJ: Возвращает анонимный объект, с именами свойств, соответствующих столбцам.
Выше приведенный код не имеет обратной связи на случай отсутствия результата. Исправим ситуацию:
$stmt->execute(array('id' => $id)); # Получаем массив, который содержит все строки результата $result = $stmt->fetchAll(); # Если получена одна или более строк... if ( count($result) ) { foreach($result as $row) { print_r($row); } } else { echo "Ничего не найдено."; }
Полный код будет выглядеть следующим образом:
$id = 5; try { $conn = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password); $stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id'); $stmt->execute(array('id' => $id)); $result = $stmt->fetchAll(); if ( count($result) ) { foreach($result as $row) { print_r($row); } } else { echo "Ничего не найдено."; } } catch(PDOException $e) { echo 'ERROR: ' . $e->getMessage(); }
Многократное выполнение
PDO проявляет свою силу в случаях, когда надо выполнить один и тот же запрос SQL несколько раз, но с разными параметрами.
try { $conn = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); # Подготавливаем запрос один раз $stmt = $conn->prepare('INSERT INTO someTable VALUES(:name)'); $stmt->bindParam(':name', $name); # Первое выполнение $name = 'Keith'; $stmt->execute(); # Второе выполнение $name = 'Steven'; $stmt->execute(); } catch(PDOException $e) { echo $e->getMessage(); }
Как только запрос подготовлен, его можно выполнить несколько раз с разными параметрами. Выше приведенный код вставляет две строки в базу данных: одна с именем “Kevin,” а другая - “Steven.”
Типовые операции с базой данных (CRUD)
Рассмотрим выполнение типовых операций с данными (CRUD - Create, Read, Update, Delete создание, чтение, обновление, удаление). Обратите внимание, что код для них будет очень похожим.
Создание (Вставка)
try { $pdo = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $pdo->prepare('INSERT INTO someTable VALUES(:name)'); $stmt->execute(array( ':name' => 'Justin Bieber' )); # Изменено строк? echo $stmt->rowCount(); // 1 } catch(PDOException $e) { echo 'Error: ' . $e->getMessage();
Обновление
$id = 5; $name = "Joe the Plumber"; try { $pdo = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $pdo->prepare('UPDATE someTable SET name = :name WHERE id = :id'); $stmt->execute(array( ':id' => $id, ':name' => $name )); echo $stmt->rowCount(); // 1 } catch(PDOException $e) { echo 'Error: ' . $e->getMessage(); }
Удаление
$id = 5; try { $pdo = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $pdo->prepare('DELETE FROM someTable WHERE id = :id'); $stmt->bindParam(':id', $id); // Воспользуемся методом bindParam $stmt->execute(); echo $stmt->rowCount(); // 1 } catch(PDOException $e) { echo 'Error: ' . $e->getMessage(); }
Результат в виде объекта
Одним из замечательных свойств PDO (а также и mysqli) является возможность представления результата запроса в виде экземпляра класса или объекта. Например:
class User { public $first_name; public $last_name; public function full_name() { return $this->first_name . ' ' . $this->last_name; } } try { $pdo = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $result = $pdo->query('SELECT * FROM someTable'); # Выводим результат как объект $result->setFetchMode(PDO::FETCH_CLASS, 'User'); while($user = $result->fetch()) { # Вызываем наш метод full_name echo $user->full_name(); } } catch(PDOException $e) { echo 'Error: ' . $e->getMessage(); }
Заключение
Если вы все еще используете старый API mysql
для работы с базой данных, то следует остановиться. Несмотря на то, что он еще не считается устаревшим, код будет иметь более высокий уровень безопасности и поддержки, если перевести его на PDO.
Источник: http://feedproxy.google.com/~r/ruseller/CdHX/~3/NdlDVS4f4cg/lessons.php
Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2024-05-06 » Как настраивать конверсионные стратегии: работа над ошибками
- 2024-04-22 » Комментирование кода и генерация документации в PHP
- 2024-04-22 » SEO в России и на Западе: в чем основные отличия
- 2024-04-22 » SEO для международного масштабирования
- 2024-04-22 » Как использовать XML-карты для продвижения сайта
- 2024-04-22 » Цифровой маркетинг: инструменты для продвижения и рекламы в 2024 году
- 2024-04-22 » Что такое CSS-модули и зачем они нам?
- 2024-04-17 » 23 сервиса для эффективного экспресс-аудита любого сайта
- 2024-04-08 » Яндекс переходит на новую версию Wordstat
- 2024-04-08 » Яндекс интегрировал в свой облачный сервис эмпатичную нейросеть
- 2024-04-08 » Новая версия нейросети Claude превзошла по мощности аналоги Google и OpenAI
- 2024-04-08 » Как пользоваться GPT 4 и Claude бесплатно и без VPN
- 2024-03-13 » Стратегии SEO на 2024 год
- 2024-03-13 » Как использовать анимацию с помощью JavaScript-библиотеки GSAP
- 2024-03-13 » Использование GSAP 3 для веб-анимации
- 2024-03-13 » Cогласование топографической съёмки с эксплуатирующими организациями
- 2024-02-19 » Теряются лиды? Как настроить сквозную аналитику
- 2024-02-17 » Мерч и IT: на что обратить внимание в 2024 году
- 2024-02-16 » Копируем с RSync: основные примеры синхронизации файлов
- 2024-02-15 » Лучшие noCode AI платформы для создания диалоговых ботов
- 2024-02-14 » Факторы ранжирования Google 2024 — исследование Semrush
- 2024-02-12 » Перенос сайта на другой хостинг
- 2024-02-05 » В России сформирован реестр хостинг-провайдеров
- 2024-02-04 » Использование SSH для подключения к удаленному серверу Ubuntu
- 2024-02-03 » Подключаемся к серверу за NAT при помощи туннеля SSH. Простая и понятная инструкция
- 2024-02-02 » Настройка CI/CD для Gitlab-репозитория: схемы и гайд по шагам
- 2024-02-01 » GitLab CI Pipeline. Запуск сценария через SSH на удаленном сервере
- 2024-01-29 » Introduction to GitLab’s CI/CD for Continuous Deployments
- 2024-01-26 » Настройка GitLab CI/CD
- 2024-01-25 » Установка shell gitlab runner
"Самый чепуховый и бесперспективный проект, но уже запущенный и работающий в Сети, принесет гораздо больше результатов и прибыли, чем самый совершенный проект, который из-за своего постоянного предстартового совершенствования никогда не будет запущен." |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.