С релизом PHP 5.1 появился новый абстрактный слой баз данных (БД) – PDO (PHP Data Objects).
Назначение:
Поддерживает следующие драйверы БД:
PDO состоит из двух частей:
Как обычно, для просмотра доступности библиотеки смотрим вывод phpinfo().
Примеры использования:
Установка подключения к MySql:
try {
$db = new PDO(‘mysql:host=localhost;dbname=testdb’, $login, $passwd);
} catch (PDOException $e) {
echo $e->getMessage();
}
// закрытия соединения и освобождение ресурсов
$db = NULL;
PDO предоставляет два способа выполнения запроса:
Запросы которые модифицируют информацию выполняются через метод exec():
$db->exec(“INSERT INTO users (login) VALUES(‘john’)”); $id = $db->lastInsertId(); $db->exec(“UPDATE user SET login=‘alex’”)
Метод exec возвращает значение – количество затронутых рядов, или FALSE в случаи ошибки.
Запросы которые получают информацию, выполняются через метод query():
$res = $db->query(“SELECT * FROM users”);
Возвращаемое значение FALSE в случаи ошибки.
Экранирование спец символов (escaping значений): $db->quote($_POST[‘login’])
Возможные способы выборки данных:
Выборка массива:
$res = $db->query(“SELECT * FROM users”);
while ($row = $res->fetch(PDO::FETCH_NUM)){
// $row - массив с числовыми ключами
}
$res = $db->query(“SELECT * FROM users”);
while ($row = $res->fetch(PDO::FETCH_ASSOC)){
// $row - ассоциативный массив значений, ключи - названия столбцов
}
$res = $db->query(“SELECT * FROM users”);
while ($row = $res->fetch(PDO::FETCH_BOTH)){
// $row - числовой и ассоиативный массив
}
Выборка одного столбца:
$column = $db->query(“SELECT id FROM users WHERE login=‘login’ AND password=‘password’”); $user = $column->fetchColumn())
Выборка объекта:
$res = $db->query(“SELECT * FROM users”);
while ($obj = $res->fetch(PDO::FETCH_OBJ)) {
// $obj - экземпляр объекта stdClass, имена столбцов - свойства объекта
}
Выборка в виде итератора (интерфейс Итератор)
$res = $db->query(“SELECT * FROM users”, PDO::FETCH_ASSOC);
foreach ($res as $row) {
// $row - ассоциативный массив значений
}
Ленивая выборка – возвращает результат в виде объекта, но фактическое наполнение объекта значением происходит только при первом обращении к этому полю:
$res = $db->query(“SELECT * FROM users”, PDO::FETCH_LAZY);
foreach ($res as $row) {
echo $row[‘name’]; // получение значения
}
Получение всех значений выборки сразу:
$qry = “SELECT * FROM users”; $res = $db->query($qry)->fetchAll(PDO::FETCH_ASSOC); // $res - массив всей выборки, каждая строка представлена ассоциативным массивом
Обработка cllback-функцией результата выборки:
function add_salt($login,$passw) { … }
$res = $db->query(“SELECT * FROM users”);
$res->fetchAll(PDO::FETCH_FUNC, “add_salt”);
Возможности запросов с заранее подготовленным выполнением:
Пример запроса:
$stmt = $db->prepare(“SELECT * FROM users WHERE id=?”); $stmt->execute(array($_GET[‘id’])); $stmt->fetch(PDO::FETCH_ASSOC);
Параметры для запроса могут быть даны в виде имен и быть привязаны к переменным:
$db->prepare('SELECT * FROM users WHERE name=:name AND email=:email');
$db->execute(array(':name'=>john,':email'=>'john@domain.com'));
$result = $db->fetchAll();
print_r($result);
$dbh->execute(array(':name'=>'alex',':email'=>'alex@domain.com'));
print_r($result);
// пример использования метода bindParam()
try{
$sql = $db->prepare("INSERT INTO USERS(name,email) VALUES (:name,:email)");
$sql->bindParam(':name',$name);
$sql->bindParam(':email',$email);
// назначение значений и вставка новой строки
$name='Joy';
$email='joy@domain.com';
$dbh->exec();
$name='debian';
$email='debian@domain.com';
$dbh->exec();
}
catch(PDOException $e) {
$dbh->rollBack();
echo 'Error : '.$e->getMessage();
}
Транзакции. Почти все драйверы PDO могут работать с транзакциями:
$db->beginTransaction();
if ($db->exec($qry) === FALSE) {
$db->rollback();
}
$db->commit();
Получение meta информации о запросе – количество столбцов и информация о всех столбцах:
$res = $db->query($qry);
$ncols = $res->columnCount();
for ($i=0; $i < $ncols; $i++) {
$meta_data = $res->getColumnMeta($i);
}
Расширение возможностей PDO:
class DB extends PDO
{
function query($qry, $mode=NULL)
{
$res = parent::query($qry, $mode);
if (!$res) {
var_dump($qry, $this->errorInfo());
return null;
} else {
return $res;
}
}
}
Дополнительный материал: