Ошибки и их обработка
PDO предлагает на выбор 3 стратегии обработки ошибок в зависимости от вашего
стиля разработки приложений.
-
PDO::ERRMODE_SILENT
До PHP 8.0.0, это был режим по умолчанию. PDO просто предоставит вам код ошибки, который
можно получить методами PDO::errorCode() и
PDO::errorInfo(). Эти методы реализованы как в объектах
запросов, так и в объектах баз данных. Если ошибка вызвана во время выполнения
кода объекта запроса, нужно вызвать метод
PDOStatement::errorCode() или
PDOStatement::errorInfo() этого объекта. Если ошибка
вызова объекта базы данных, нужно вызвать аналогичные методы у этого объекта. -
PDO::ERRMODE_WARNING
Помимо установки кода ошибки PDO выдаст обычное E_WARNING сообщение. Это может
быть полезно при отладке или тестировании, когда нужно видеть, что произошло,
но не нужно прерывать работу приложения. -
PDO::ERRMODE_EXCEPTION
Начиная с PHP 8.0.0 является режимом по умолчанию. Помимо задания кода ошибки PDO будет выбрасывать исключение
PDOException, свойства которого будут отражать
код ошибки и её описание. Этот режим также полезен при отладке, так как
сразу известно, где в программе произошла ошибка. Это позволяет быстро
локализовать и решить проблему. (Не забывайте, что если исключение
является причиной завершения работы скрипта, все активные транзакции
будут откачены.)Режим исключений также полезен, так как даёт возможность структурировать
обработку ошибок более тщательно, нежели с обычными предупреждениями PHP, а
также с меньшей вложенностью кода, чем в случае работы в тихом режиме с
явной проверкой возвращаемых значений при каждом обращении к базе данных.Подробнее об исключениях в PHP смотрите в разделе Исключения.
PDO стандартизирован для работы со строковыми кодами ошибок SQL-92 SQLSTATE.
Отдельные драйверы PDO могут задавать соответствия своих собственных кодов
кодам SQLSTATE. Метод PDO::errorCode() возвращает одиночный
код SQLSTATE. Если необходима специфичная информация об ошибке, PDO предлагает
метод PDO::errorInfo(), который возвращает массив, содержащий
код SQLSTATE, код ошибки драйвера, а также строку ошибки драйвера.
Пример #1 Создание PDO объекта и установка режима обработки ошибок
<?php
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';$dbh = new PDO($dsn, $user, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);// PDO выбросит исключение PDOException (если таблица не существует)
$dbh->query("SELECT wrongcolumn FROM wrongtable");
?>
Результат выполнения данного примера:
Fatal error: Uncaught PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'testdb.wrongtable' doesn't exist in /tmp/pdo_test.php:10 Stack trace: #0 /tmp/pdo_test.php(10): PDO->query('SELECT wrongcol...') #1 {main} thrown in /tmp/pdo_test.php on line 10
Замечание:
Метод PDO::__construct() будет всегда бросать исключение PDOException,
если соединение оборвалось, независимо от установленного значенияPDO::ATTR_ERRMODE
.
Пример #2 Создание экземпляра класса PDO и установка режима обработки ошибок в конструкторе
<?php
$dsn = 'mysql:dbname=test;host=127.0.0.1';
$user = 'googleguy';
$password = 'googleguy';$dbh = new PDO($dsn, $user, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));// Следующий запрос приводит к ошибке уровня E_WARNING вместо исключения (когда таблица не существует)
$dbh->query("SELECT wrongcolumn FROM wrongtable");
?>
Результат выполнения данного примера:
Warning: PDO::query(): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.wrongtable' doesn't exist in /tmp/pdo_test.php on line 9
There are no user contributed notes for this page.
$st = $db->prepare("SELECT * FROM c6ode");
How can I check the intentional mysql error for the query in above case?
asked Jan 8, 2012 at 8:41
0
You need to set the error mode attribute PDO::ATTR_ERRMODE
to PDO::ERRMODE_EXCEPTION
.
And since you expect the exception to be thrown by the prepare()
method, you should disable the PDO::ATTR_EMULATE_PREPARES
feature. Otherwise the MySQL server doesn’t «see» the statement until it’s executed.
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->prepare('INSERT INTO DoesNotExist (x) VALUES (?)');
prints (or logs, depends on the PHP settings)
SQLSTATE[42S02]: Base table or view not found:
1146 Table 'test.doesnotexist' doesn't exist
answered Jan 8, 2012 at 8:52
VolkerKVolkerK
95.5k20 gold badges164 silver badges227 bronze badges
1
I’m using this without any additional settings:
if (!$st->execute()) {
print_r($st->errorInfo());
}
The Codesee
3,7145 gold badges38 silver badges78 bronze badges
answered Jan 8, 2012 at 8:48
ladarladar
5,8583 gold badges26 silver badges38 bronze badges
0
I’m guessing that your complaint is that the exception is not firing. PDO is most likely configured to not throw exceptions. Enable them with this:
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
answered Jan 8, 2012 at 8:45
Steve RukutsSteve Rukuts
9,1773 gold badges50 silver badges72 bronze badges
2
a quick way to see your errors whilst testing:
$error= $st->errorInfo();
echo $error[2];
answered Jan 15, 2014 at 11:19
LanLan
1,8742 gold badges20 silver badges37 bronze badges
0
/* Provoke an error — the BONES table does not exist */
$sth = $dbh->prepare('SELECT skull FROM bones');
$sth->execute();
echo "\nPDOStatement::errorInfo():\n";
$arr = $sth->errorInfo();
print_r($arr);
output
Array
(
[0] => 42S02
[1] => -204
[2] => [IBM][CLI Driver][DB2/LINUX] SQL0204N "DANIELS.BONES" is an undefined name. SQLSTATE=42704
)
answered Jul 5, 2017 at 9:07
1
Вернуться к: PDO
PDO предлагает на выбор 3 стратегии обработки ошибок в зависимости от вашего
стиля разработки приложений.
-
PDO::ERRMODE_SILENT
Это режим по умолчанию. PDO просто предоставит вам код ошибки, который
можно получить методами PDO::errorCode() и
PDO::errorInfo(). Эти методы реализованы как в объектах
запросов так и в объектах баз данных. Если ошибка вызвана во время выполнения
кода объекта запроса, нужно вызвать метод
PDOStatement::errorCode() или
PDOStatement::errorInfo() этого объекта. Если ошибка
вызова объекта базы данных, нужно вызвать аналогичные методы у этого объекта. -
PDO::ERRMODE_WARNING
Помимо задания кода ошибки PDO выдаст обычное E_WARNING сообщение. Это может
быть полезно при отладке или тестировании, когда нужно видеть, что произошло,
но не нужно прерывать работу приложения. -
PDO::ERRMODE_EXCEPTION
Помимо задания кода ошибки PDO будет выбрасывать исключение
PDOException, свойства которого будут отражать
код ошибки и ее описание. Этот режим также полезен при отладке, так как
сразу известно, где в программе произошла ошибка. Это позволяет быстро
локализовать и решить проблему. (Не забывайте, что если исключение
является причиной завершения работы скрипта, все активные транзакции
будут откачены.)Режим исключений также полезен, так как дает возможность структурировать
обработку ошибок более тщательно, нежели с обычными PHP предупреждениями, а
также с меньшей вложенностью кода, чем в случае работы в тихом режиме с
явной проверкой возвращаемых значений при каждом обращении к базе данных.Подробнее об исключениях в PHP см. в разделе Исключения.
PDO стандартизирован для работы со строковыми кодами ошибок SQL-92 SQLSTATE.
Отдельные PDO драйверы могут задавать соответствия своих собственных кодов
кодам SQLSTATE. Метод PDO::errorCode() возвращает одиночный
SQLSTATE код. Если необходима специфичная информация об ошибке, PDO предлагает
метод PDO::errorInfo(), который возвращает массив, содержащий
SQLSTATE код, код ошибки драйвера, а также строку ошибки драйвера.
Пример #1 Создание PDO объекта и задание режима обработки ошибок
<?php
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
try {
$dbh = new PDO($dsn, $user, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Подключение не удалось: ' . $e->getMessage();
}?>
Замечание:
Метод PDO::__construct() будет всегда бросать исключение PDOException,
если соединение оборвалось, независимо от установленного значенияPDO::ATTR_ERRMODE
.
Непойманные исключения фатальны.
Пример #2 Создание экземпляра класса PDO и задание режима обработки ошибок в конструкторе
<?php
$dsn = 'mysql:dbname=test;host=127.0.0.1';
$user = 'googleguy';
$password = 'googleguy';/*
По прежнему оберните конструктор в блок try/catch, так как, даже при установке ERRMODE в WARNING,
PDO::__construct всегда будет бросать исключение PDOException, если соединение оборвалось.
*/
try {
$dbh = new PDO($dsn, $user, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
} catch (PDOException $e) {
echo 'Соединение оборвалось: ' . $e->getMessage();
exit;
}// Следующий запрос приводит к ошибке уровня E_WARNING вместо исключения (когда таблица не существует)
$dbh->query("SELECT wrongcolumn FROM wrongtable");
?>
Результат выполнения данного примера:
Warning: PDO::query(): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.wrongtable' doesn't exist in /tmp/pdo_test.php on line 18
Вернуться к: PDO
В этой статье разговор пойдет о PHP Data Objects (PDO) — расширение для PHP, предоставляющее разработчику универсальный интерфейс для доступа к различным базам данных.
В чем преимущество PDO? Этот вопрос можно раскрыть тремя пунктами:
- Универсальный интерфейс для работы с различными базами данных. Разработчик может легко перевести свое веб-приложение на другую СУБД, поменяв при этом всего пару строк кода.
- Высокая скорость работы.
- Подготовленные выражения, о которых мы поговорим чуть позже.
На данный момент расширение PDO может поддерживать СУБД для которой существует PDO-драйвер:
- PDO_CUBRID (CUBRID)
- PDO_DBLIB (FreeTDS, Microsoft SQL Server, Sybase)
- PDO_FIREBIRD (Firebird, Interbase 6)
- PDO_IBM (IBM DB2)
- PDO_INFORMIX (IBM Informix Dynamic Server)
- PDO_MYSQL (MySQL 3.x/4.x/5.x)
- PDO_OCI (Oracle Call Interface)
- PDO_ODBC (ODBC v3 (IBM DB2, unixODBC and win32 ODBC))
- PDO_PGSQL (PostgreSQL)
- PDO_SQLITE (SQLite 3 and SQLite 2)
- PDO_SQLSRV (Microsoft SQL Serve )
- PDO_4D (4D)
Подключение к базе данных
В зависимости от выбранной СУБД, способ подключения может незначительно отличаться. Подключение к популярным СУБД:
// MуSQL $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); // PostgreSQL $DBH = new PDO("pgsql:host=$host;dbname=$dbname", $user, $pass); //MS SQL $DBH = new PDO("mssql:host=$host;dbname=$dbname", $user, $pass); // SQLite $DBH = new PDO("sqlite:my/database/path/database.db");
Обработка ошибок и исключения
Обязательно заключайте подключение к базе данных в блок try/catch:
try { $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); } catch(PDOException $e) { echo "Нет соединения с базой данных"; }
Иначе, в случае ошибки, в браузер будет выкинут Fatal error, в котором будут раскрыты все подробности вашего соединения, с логином и паролем.
PDO умеет выбрасывать исключения при ошибках, поэтому все операции с базой, по хорошему, должны находиться в блоке try/catch.
PDO имеет три режима обработки исключения:
- PDO::ERRMODE_SILENT — режим по умолчанию, ошибки генерируются по такому же принципу, как в расширениях mysql или mysqli. После возникновения ошибки скрипт продолжит работу.
- PDO::ERRMODE_WARNING — режим вызовет стандартное сообщение E_WARNING и позволит скрипту продолжить работу.
- PDO::ERRMODE_EXCEPTION — режим выбрасывает исключение, что позволяет обрабатывать ошибки и скрывать важную информацию от посторонних глаз.
Чтобы установить необходимый уровень контроля ошибок необходимо вызвать метод $this->setAttribute после подключения к базе данных.
try { $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $e) { echo "Нет соединения с базой данных"; }
Подготовленные выражения или Prepared Statements
Подготовленные выражения — это заранее скомпилированное SQL-выражение, которое может быть многократно выполнено путем отправки серверу лишь различных наборов данных. Дополнительным преимуществом является невозможность провести SQL-инъекцию.
За подготовленные выражения отвечает метод $DBH->prepare. Им и рекомендуется всегда пользоваться.
Сразу хочу отметить, что выполнить запрос в PDO можно тремя методами:
- $DBH->exec — используется для запросов, которые не возвращают никаких данных. Метод возвращает количество затронутых им записей, или FALSE в случае ошибки.
$count_row = $DBH->exec("DELETE FROM users");
- $DBH->query – используется выполнения не защищенных запросов, и возвращает результат или FALSE в случаи ошибки. Например, им можно выполнять простые запросы.
$DBH->query("SET NAMES 'cp1251'"); $DBH->query("SELECT * FROM users"); $DBH->query("DELETE FROM users");
- $DBH->prepare + $STH->execute — используется для подготовки выражений и выполнения запроса.
// безымянные placeholders $STH = $DBH->prepare("INSERT INTO users (name, phone, city) values (?, ?, ?)");
// именные placeholders $STH = $DBH->prepare("INSERT INTO users (name, phone, city) values (:name, :phone, :city)");
После подготовки, запрос выполняется методом $STH->execute($data).
// безымянные placeholders $data = array(); $data[] = 'Alersander'; $data[] = '+7 000 123 45 67'; $data[] = 'St. Petersburg'; $STH = $DBH->prepare("INSERT INTO users (name, phone, city) values (?, ?, ?)"); $STH->execute($data);
// именные placeholders $data = array(); $data['name'] = 'Alersander'; $data['phone'] = '+7 000 123 45 67'; $data['city'] = 'St. Petersburg'; $STH = $DBH->prepare("INSERT INTO users (name, phone, city) values (:name, :phone, :city)"); $STH->execute($data);
Выборка данных
Для выборки с произвольными параметрами тоже будем использовать метод $DBH->prepare. Данные выборки можно получить с помощью методов:
- $STH->fetch — выбирает следующую строку и возвращает в необходимом виде.
- $STH->fetchAll — возвращает массив всех выбранных строк.
- $STH->fetchObject — выбирает следующую строку и возвращает ее как объект.
Я буду рассматривать только первый метод, т.к. он универсальный и предоставляет разработчику, всё, что ему необходимо.
Методу $STH->fetch можно указать, в каком виде нам нужно предоставить результат:
- PDO::FETCH_BOTH (по умолчанию) — возвращает числовой и ассоциативный массив;
- PDO::FETCH_ASSOC — возвращает массив ассоциативный с названиями столбцов;
- PDO::FETCH_NUM — возвращает массив числовыми ключами в виде порядковых номеров столбцов;
- PDO::FETCH_OBJ — возвращает анонимный объект со свойствами, соответствующими именам столбцов;
- PDO::FETCH_BOUND — присваивает значения столбцов соответствующим переменным, заданным с помощью метода $STH->bindColumn();
- PDO::FETCH_CLASS — присваивает значения столбцов соответствующим свойствам указанного класса. Если для какого-то столбца свойства нет, оно будет создано;
- PDO::FETCH_INTO — обновляет существующий экземпляр указанного класса;
- PDO::FETCH_LAZY — объединяет в себе PDO::FETCH_BOTH и PDO::FETCH_OBJ.
$STH = $DBH->prepare("SELECT name, phone, city FROM users"); $STH->execute(); while($res = $STH->fetch(PDO::FETCH_ASSOC)) { echo $res['name']; } $STH = $DBH->prepare("SELECT name, phone, city FROM users"); $STH->execute(); while($res = $STH->fetch(PDO::FETCH_OBJ)) { echo $res->name; }
Закрытие соединения и освобождение буфера запроса
В PDO нет специальных методов для этих целей. Закрыть соединение с базой данных можно путем переопределения переменных:
$DBH = null; $STH = null;
Полезные методы
- $DBH->lastInsertId() — возвращает id последней вставленной записи.
- $DBH->query(string) — экранирует специальные символы в строковых данных таким образом, что их становится безопасно использовать в запросах.
- $STH->rowCount() — возвращает количество затронутых записей последним запросом.
Обработка ошибок PDO
Лично мне не нравится, что если я не заключаю все запросы в блок try/catch, то PDO выкидывает Fatal error со всеми интимными подробностями моего запроса. В промышленном приложении заключать каждый запрос в блок try/catch, это идиотизм!
Поэтому мы поступим следующим образом — немного расширим классы PDO и PDOStatement:
class DB extends PDO { public $error = false; // выводить сообщения об ошибках на экран? (true/false) public function __construct($dsn, $username='', $password='', $driver_options=array()) { try { parent::__construct($dsn, $username, $password, $driver_options); $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('DBStatement', array($this))); $this->query("SET NAMES 'cp1251'"); } catch(PDOException $e) { echo "Произошла ошибка в работе с базой данных..."; exit(); } } public function prepare($sql, $driver_options=array()) { try { return parent::prepare($sql, $driver_options); } catch(PDOException $e) { $this->error($e->getMessage()); } } public function query($sql) { try { return parent::query($sql); } catch(PDOException $e) { $this->error($e->getMessage()); } } public function exec($sql) { try { return parent::exec($sql); } catch(PDOException $e) { $this->error($e->getMessage()); } } public function error($msg) { if($this->error) { echo $msg; } else { echo "Произошла ошибка в работе с базой данных..."; } exit(); } }
class DBStatement extends PDOStatement { protected $DBH; protected function __construct($DBH) { $this->DBH = $DBH; } public function execute($data=array()) { try { return parent::execute($data); } catch(PDOException $e) { $this->DBH->error($e->getMessage()); } } }
Как видите, я реализую свои два класса DB и DBStatement, наследуя классы PDO и PDOStatement. Классы реализуют все необходимые мне для работы над ошибками методы, которые обрабатываются блоком try/catch.
$DBH = new DB("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->error = true; // Для отладки выводим сообщения об ошибках на экран. $STH = $DBH->prepare("SELEC * FROM users"); $STH->execute($data);
Как видите, я совершил опечатку в операторе и могу получить всю необходимую информацию об этой ошибке.
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELEC * FROM users' at line 1
Расширение функционала
Также бывает полезно расширить функционал PDO. Например, часто требуется получить количество записей в таблице.
Стандартными методами это можно делать следующим образом:
$data = array(); $data['user_id'] = 1; $STH = $DBH->prepare("SELECT COUNT(*) as count FROM users WHERE user_id=:user_id"); $STH->execute($data); echo $STH->fetch(PDO::FETCH_OBJ)->count;
Не слишком удобно. Поэтому реализуем в нашем классе методом count:
class DB extends PDO { // .................. public function count($sql, $data) { $res = $this->prepare($sql); $res->execute($data); return $res->fetch(PDO::FETCH_OBJ); } // .................. }
Получаем количество записей:
$DBH = new DB("mysql:host=$host;dbname=$dbname", $user, $pass); echo $DBH->count("SELECT COUNT(*) as count FROM users WHERE user_id=:user_id", array('user_id'=>'1'))->count;
Свои методы это конечно хорошо, но мне бы ещё хотелось писать все одной строкой. К сожалению, стандартными возможностями я не могу этого сделать:
$res = $DBH->prepare("SELECT * FROM users WHERE id_user=:id_user") ->execute(array('id_user'=>'1')) ->fetch(PDO::FETCH_ASSOC); echo $res['name']; // или так echo $DBH->prepare("SELECT *FROM users WHERE id_user=:id_user") ->execute(array('id_user'=>'1')) ->fetch(PDO::FETCH_OB) ->name;
Метод execute возвращает бесполезное логическое значение об успехе операции, а не объект DBStatement.
Допиливаем свой метод execute:
public function execute($data=array()) { try { parent::execute($data); return $this; } catch(PDOException $e) { $this->DBH->error($e->getMessage()); } }
Проверяем результат:
echo $DBH->prepare("SELECT COUNT(*) as count FROM users WHERE city=:city") ->execute(array('city'=>'St. Petersburg')) ->fetch(PDO::FETCH_OBJ) ->count;
Источник
Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Answer by Edwin Bryan
Meta Stack Overflow
,
Stack Overflow
Public questions & answers
,Thanks for contributing an answer to Stack Overflow!,Stack Overflow em Português
You need to set the error mode attribute PDO::ATTR_ERRMODE to PDO::ERRMODE_EXCEPTION.
And since you expect the exception to be thrown by the prepare() method you should disable the PDO::ATTR_EMULATE_PREPARES* feature. Otherwise the MySQL server doesn’t «see» the statement until it’s executed.
<?php
try {
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->prepare('INSERT INTO DoesNotExist (x) VALUES (?)');
}
catch(Exception $e) {
echo 'Exception -> ';
var_dump($e->getMessage());
}
prints (in my case)
Exception -> string(91) "SQLSTATE[42S02]: Base table or view not found:
1146 Table 'test.doesnotexist' doesn't exist"
*) and then there’s PDO::MYSQL_ATTR_DIRECT_QUERY — I must admit that I don’t understand the interaction of those two attributes (yet?), so I set them both, like
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly', array(
PDO::ATTR_EMULATE_PREPARES=>false,
PDO::MYSQL_ATTR_DIRECT_QUERY=>false,
PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION
));
Answer by Harley Ware
PDO::errorInfo —
Fetch extended error information associated with the last operation on the database handle
,
PDO::errorInfo() returns an array of error information
about the last operation performed by this database handle. The array
consists of at least the following fields:
,PDOStatement::errorInfo() — Fetch extended error information associated with the last operation on the statement handle,PDO::errorCode() — Fetch the SQLSTATE associated with the last operation on the database handle
PDO::errorInfo():
Array
(
[0] => HY000
[1] => 1
[2] => near "bogus": syntax error
)
Answer by Kaiya Dean
You need to set the error mode attribute PDO::ATTR_ERRMODE to PDO::ERRMODE_EXCEPTION.
And since you expect the exception to be thrown by the prepare() method you should disable the PDO::ATTR_EMULATE_PREPARES* feature. Otherwise the MySQL server doesn’t «see» the statement until it’s executed.,Exception handling in java,Python interview questions,Robotic Process Automation Training using UiPath
try {
$db = new PDO("mysql:host=".HOST.";dbname=".DB, USER, PW);
$st = $db->prepare("SELECT * FROM c6ode");
}
catch (PDOException $e){
echo $e->getMessage();
}
Answer by Taylor Murray
In order to output the PDO error you will need to get the error info from the statement object. To implement this function simply add the or die code to the end of the $stmt->execute code.,Often it can be quite hard to debug SQL errors when using PHP since PHP will often throw a generic error that doesn’t really help you diagnose the situation. Other times you may not want to allow PHP errors to be shown. A quick way to debug PDO SQL errors is to use the or die function. “or die” works by executing the SQL query and if it fails to execute it will “die” and output the contents of the function. This is quite similar to a try catch block.,The code snippet above will dump the entire error onto the web page. Very useful in development, but not in production. Please be careful and use an internal logging system to keep track of database errors on a production website.,This site uses Akismet to reduce spam. Learn how your comment data is processed.
In order to output the PDO error you will need to get the error info from the statement object. To implement this function simply add the or die code to the end of the $stmt->execute code.
$stmt = $db->prepare($sql);
$stmt->execute($array) or die(print_r($stmt->errorInfo(), true));
Answer by Jada Stark
The driver-specific error message.,The driver-specific error message.
,Starting with 5.9.0, the default behavior of PDO::errorInfo is to show additional ODBC errors, if they are available. For example:,The driver-specific error code.
Syntax
array PDO::errorInfo();
In this example, the name of the column is misspelled (Cityx
instead of City
), causing an error, which is then reported.
<?php
$conn = new PDO( "sqlsrv:server=(local) ; Database = AdventureWorks ", "");
$query = "SELECT * FROM Person.Address where Cityx = 'Essen'";
$conn->query($query);
print $conn->errorCode();
echo "\n";
print_r ($conn->errorInfo());
?>
When an exception occurs, the ODBC Driver may return more than one error to help diagnose problems. However, PDO::errorInfo always shows only the first error. In response to this bug report, PDO::errorInfo and PDOStatement::errorInfo have been updated to indicate that drivers should display at least the following three fields:
0 SQLSTATE error code (a five characters alphanumeric identifier defined in the ANSI SQL standard).
1 Driver specific error code.
2 Driver specific error message.
Starting with 5.9.0, the default behavior of PDO::errorInfo is to show additional ODBC errors, if they are available. For example:
<?php
try {
$conn = new PDO("sqlsrv:server=$server;", $uid, $pwd);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare("SET NOCOUNT ON; USE $database; SELECT 1/0 AS col1");
$stmt->execute();
} catch (PDOException $e) {
var_dump($e->errorInfo);
}
?>
Running the above script should have thrown an exception, and the output is like this:
array(6) {
[0]=>
string(5) "01000"
[1]=>
int(5701)
[2]=>
string(91) "[Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Changed database context to 'tempdb'."
[3]=>
string(5) "22012"
[4]=>
int(8134)
[5]=>
string(87) "[Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Divide by zero error encountered."
}
If the user prefers the previous way, a new configuration option pdo_sqlsrv.report_additional_errors
can be used to turn it off. Simply add the following line in the beginning of any php script:
ini_set('pdo_sqlsrv.report_additional_errors', 0);
In this case, the error info shown will be like this, when running the same example script:
array(3) {
[0]=>
string(5) "01000"
[1]=>
int(5701)
[2]=>
string(91) "[Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Changed database context to 'tempdb'."
}
If necessary, the user may choose to add the following line to the php.ini file in order to turn off this feature in all their php scripts:
pdo_sqlsrv.report_additional_errors = 0
Beginning with 5.9.0, ODBC warnings will no longer be logged as errors. That is, error codes with prefix «01» are logged as warnings. In other words, if the user wants to log errors only, update the php.ini like this:
[pdo_sqlsrv]
pdo_sqlsrv.log_severity = 1
Answer by Chloe Beck
To retrieve a single row by its id column value, use the find method:,The Laravel query builder uses PDO parameter binding to protect your application against SQL injection attacks. There is no need to clean or sanitize strings passed to the query builder as query bindings.,The whereNotBetween method verifies that a column’s value lies outside of two values:,The whereNull method verifies that the value of the given column is NULL:
You may use the table
method provided by the DB
facade to begin a query. The table
method returns a fluent query builder instance for the given table, allowing you to chain more constraints onto the query and then finally retrieve the results of the query using the get
method:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
class UserController extends Controller
{
/**
* Show a list of all of the application's users.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$users = DB::table('users')->get();
return view('user.index', ['users' => $users]);
}
}
The get
method returns an Illuminate\Support\Collection
instance containing the results of the query where each result is an instance of the PHP stdClass
object. You may access each column’s value by accessing the column as a property of the object:
use Illuminate\Support\Facades\DB;
$users = DB::table('users')->get();
foreach ($users as $user) {
echo $user->name;
}
If you just need to retrieve a single row from a database table, you may use the DB
facade’s first
method. This method will return a single stdClass
object:
$user = DB::table('users')->where('name', 'John')->first();
return $user->email;
If you don’t need an entire row, you may extract a single value from a record using the value
method. This method will return the value of the column directly:
$email = DB::table('users')->where('name', 'John')->value('email');
To retrieve a single row by its id
column value, use the find
method:
$user = DB::table('users')->find(3);
Answer by Paxton Grant
The query() method returns a PDOStatement object. If an error occurs, the query() method returns false.,The query() method of a PDO object.,When a query doesn’t have any parameters, you can use the query() method. For example:,Use the query() method of an PDO object to execute a SELECT statement to query data from one or more tables.
When a query doesn’t have any parameters, you can use the query()
method. For example:
.wp-block-code {
border: 0;
padding: 0;
}
.wp-block-code > div {
overflow: auto;
}
.shcb-language {
border: 0;
clip: rect(1px, 1px, 1px, 1px);
-webkit-clip-path: inset(50%);
clip-path: inset(50%);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
word-wrap: normal;
word-break: normal;
}
.hljs {
box-sizing: border-box;
}
.hljs.shcb-code-table {
display: table;
width: 100%;
}
.hljs.shcb-code-table > .shcb-loc {
color: inherit;
display: table-row;
width: 100%;
}
.hljs.shcb-code-table .shcb-loc > span {
display: table-cell;
}
.wp-block-code code.hljs:not(.shcb-wrap-lines) {
white-space: pre;
}
.wp-block-code code.hljs.shcb-wrap-lines {
white-space: pre-wrap;
}
.hljs.shcb-line-numbers {
border-spacing: 0;
counter-reset: line;
}
.hljs.shcb-line-numbers > .shcb-loc {
counter-increment: line;
}
.hljs.shcb-line-numbers .shcb-loc > span {
padding-left: 0.75em;
}
.hljs.shcb-line-numbers .shcb-loc::before {
border-right: 1px solid #ddd;
content: counter(line);
display: table-cell;
padding: 0 0.75em;
text-align: right;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
white-space: nowrap;
width: 1%;
}SELECT * FROM publishers;Code language: SQL (Structured Query Language) (sql)
The following illustrates how to query all rows from the publishers
table in the bookdb
database:
<?php
$pdo = require 'connect.php';
$sql = 'SELECT publisher_id, name
FROM publishers';
$statement = $pdo->query($sql);
// get all publishers
$publishers = $statement->fetchAll(PDO::FETCH_ASSOC);
if ($publishers) {
// show the publishers
foreach ($publishers as $publisher) {
echo $publisher['name'] . '<br>';
}
}
Code language: HTML, XML (xml)
Output:
McGraw-Hill Education
Penguin/Random House
Hachette Book Group
Harper Collins
Simon and Schuster
First, create a database connection to the bookdb
database:
$pdo = require 'connect.php';Code language: PHP (php)
Second, define an SQL SELECT
statement to select all rows from publishers
table:
$sql = 'SELECT publisher_id, name FROM publishers';Code language: PHP (php)
Third, run the query by calling the query()
method of the PDO object:
$statement = $pdo->query($sql);Code language: PHP (php)
Fourth, fetch all data from the result set:
$publishers = $statement->fetchAll(PDO::FETCH_ASSOC);Code language: PHP (php)
Finally, iterate over the result set and show the array’s element:
<?php
// show the publishers
if ($publishers) {
foreach ($publishers as $publisher) {
echo $publisher['name'] . '<br>';
}
}Code language: HTML, XML (xml)
The following example illustrates how to use a prepared statement to query data from a table:
<?php
$publisher_id = 1;
// connect to the database and select the publisher
$pdo = require 'connect.php';
$sql = 'SELECT publisher_id, name
FROM publishers
WHERE publisher_id = :publisher_id';
$statement = $pdo->prepare($sql);
$statement->bindParam(':publisher_id', $publisher_id, PDO::PARAM_INT);
$statement->execute();
$publisher = $statement->fetch(PDO::FETCH_ASSOC);
if ($publisher) {
echo $publisher['publisher_id'] . '.' . $publisher['name'];
} else {
echo "The publisher with id $publisher_id was not found.";
}
Code language: HTML, XML (xml)
First, define a publisher id. In practice, you may get it from the query string:
<?php
$publisher_id = 1;Code language: HTML, XML (xml)
Second, use the connect.php
to connect to the bookdb
database and return a new instance of the PDO object:
$pdo = require 'connect.php';Code language: PHP (php)
Third, construct an SQL SELECT statement with a named placeholder (:publisher_id
)
$sql = 'SELECT publisher_id, name
FROM publishers
WHERE publisher_id = :publisher_id';Code language: PHP (php)
Fourth, bind the value of the id to the prepared statement:
$statement->bindParam(':publisher_id', $publisher_id, PDO::PARAM_INT);Code language: PHP (php)
Fifth, execute the prepared statement:
$statement->execute();Code language: PHP (php)
Sixth, fetch a row from the result set into an associative array:
$publisher = $statement->fetch(PDO::FETCH_ASSOC);Code language: PHP (php)
Finally, show the publisher information or an error message:
if ($publisher) {
echo $publisher['publisher_id'] . '.' . $publisher['name'];
} else {
echo "The publisher with id $publisher_id was not found.";
}Code language: PHP (php)