Php работа с базой данных pdo

Доступ к базе данных в 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 , в котором необработанные ошибки будут вызывать исключения и остановку скрипта.

Читайте также:  Считать массив си шарп

Доступны следующие режимы работы с ошибками:

Получаем данные

Итак, у нас есть соединение с базой данных и теперь нужно получить данные. Есть два способа решить поставленную задачу: 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 $stmt->execute(array('id' => $id)); while($row = $stmt->fetch()) < print_r($row); >> catch(PDOException $e) < echo 'ERROR: ' . $e->getMessage(); >

В данном примере используется также метод prepare для подготовки запроса, перед тем, как присоединить данные пользователя. В таком случае инъекция SQL теоретически невозможна, так как сами данные не вставляются в текст запроса SQL. Используется именованный параметр ( :id ) для обозначения места.

Затем выполняется запрос с передачей массива, который содержит данные, которые следует использовать на месте именованного параметра.

В качестве альтернативы можно использовать метод bindParam :

$stmt->bindParam(':id', $id, PDO::PARAM_INT); $stmt->execute();

Обрабатываем данные

После вызова метода execute есть несколько способов получить данные: массив (по умолчанию), объект и так далее. В выше приведенном примере используется режим по умолчанию: PDO::FETCH_ASSOC . Его легко поменять, если нужно:

Читайте также:  System in type java lang

while($row = $stmt->fetch(PDO::FETCH_OBJ))

Теперь результат будет в виде объекта. Доступны следующие опции:

  • 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

Полный код будет выглядеть следующим образом:

$id = 5; try < $conn = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password); $stmt = $conn->prepare('SELECT * FROM myTable WHERE $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 $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 $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.

Читайте также:  Sqlite python insert json

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: net.tutsplus.com/tutorials/php/php-database-access-are-you-doing-it-correctly/
Перевел: Сергей Фастунов
Урок создан: 4 Июня 2012
Просмотров: 109933
Правила перепечатки

5 последних уроков рубрики «PHP»

Фильтрация данных с помощью zend-filter

Когда речь идёт о безопасности веб-сайта, то фраза «фильтруйте всё, экранируйте всё» всегда будет актуальна. Сегодня поговорим о фильтрации данных.

Контекстное экранирование с помощью zend-escaper

Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.

Подключение Zend модулей к Expressive

Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.

Совет: отправка информации в Google Analytics через API

Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.

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

Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

Источник

Оцените статью