Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: PDOException, RuntimeException, Exception в чем разница?

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
arimanecro
Отправлено: 04 Декабря, 2015 - 15:41:11
Post Id



Частый гость


Покинул форум
Сообщений всего: 209
Дата рег-ции: Май 2014  


Помог: 0 раз(а)




Согласно документации PDOException это наследник RuntimeException, а последний в свою очередь наследник Exception.

Из документации:
Цитата:
Метод PDO::__construct() будет всегда бросать исключение PDOException, если соединение оборвалось, независимо от установленного значения PDO::ATTR_ERRMODE


1) Спрашивается нафига, тогда нужно указывать:
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) ?

2) Зачем указывать конкретику, что это PDO - catch (PDOException $e), если я могу написать так - (Exception $e) или так (RuntimeException $e) и получаю ту же самую перехваченную ошибку.
В чем смысл одинаковых трех классов, если они делают одно и тоже?

(Отредактировано автором: 04 Декабря, 2015 - 15:42:12)

 
 Top
Мелкий Супермодератор
Отправлено: 04 Декабря, 2015 - 16:27:25
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




1) PDO::ATTR_ERRMODE задаёт поведение для дальнейших запросов.
__construct всегда исключение бросает в случае чего, а те же execute и query - уже в зависимости от ERRMODE

2) Разница в том, exception - это все возможные исключения (до 7.0.0, в 7.0.0 немного поменяли), RuntimeException - исключения, обнаруженные при выполнении кода (не обязательно базы), PDOException - именно ошибки базы.
Даёт возможность в конкретном catch ловить именно какое-то конкретное подмножество исключений.
Если указывать надмножество - то, конечно, вы будете ловить все исключения этого множества. А вот если у вас указан PDOException, а произошёл какой-нибудь LogicException - сюда он не попадёт.

К слову, обращаю внимание на изменения в вышедшем PHP7.0.0 касательно исключений: http://habrahabr[dot]ru/post/261451/


-----
PostgreSQL DBA
 
 Top
arimanecro
Отправлено: 08 Декабря, 2015 - 11:30:59
Post Id



Частый гость


Покинул форум
Сообщений всего: 209
Дата рег-ции: Май 2014  


Помог: 0 раз(а)




Мелкий -- спс, более ли менее стало ясно.

Др.вопрос: в чем смысл тогда PDO::errorCode?

PHP:
скопировать код в буфер обмена
  1. $sql = "SELECT * FROM blog7_blogshop"; // умышленная ошибка в запросе
  2.  
  3.                 $stmt = Db::$dbh->prepare($sql);
  4.                 $stmt->execute();
  5.                
  6.                if($stmt->errorCode() == 0) {
  7.                         while($row = $stmt->fetch()) {
  8.                         echo $row['title'] . br;
  9. }
  10. }
  11.                 else {
  12.                 $errors = $stmt->errorInfo();
  13.                 echo $errors[2];
  14.                 }
  15.         }


$stmt->errorInfo() -- не сработает, потому что выбросит:
Uncaught exception 'PDOException' with message 'SQLSTATE[42S02].

1)Как вообще конструкция if/else должна сработать, если выброс ПДО исключения не дает этого сделать?

2) И почему данное PDOException не перехватывается, если при создании new PDO, у меня стоит перехватчик?
 
 Top
Мелкий Супермодератор
Отправлено: 08 Декабря, 2015 - 12:00:28
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




errorCode и errorInfo нужны в первую очередь для извращенцев с PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT

Затем, их по-прежнему можно читать из catch, если есть такое желание.

arimanecro пишет:
1)Как вообще конструкция if/else должна сработать, если выброс ПДО исключения не дает этого сделать?

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

Можно сразу заниматься делом, а не ошибками:
PHP:
скопировать код в буфер обмена
  1. $stmt = Db::$dbh->prepare($sql);
  2. $stmt->execute();
  3.  
  4. foreach ($stmt as $row) {
  5.     echo $row['title'];
  6. }

Всё, здесь не нужно думать о том, что запрос может вернуть ошибку. А все исключения ловить где-нибудь на верхних уровнях проекта.
PHP:
скопировать код в буфер обмена
  1. try {
  2.    // разбор, обработка запроса от пользователя: роутинг, вызов контроллера, вызов метода
  3. } catch (Exception $e) {
  4.     // запишем в лог сообщение об ошибке
  5.     // а пользователю отдаём красивую 503
  6. }


При этом, механизм исключений позволяет легко вешать дополнительную логику:
PHP:
скопировать код в буфер обмена
  1. try {
  2. $pdo->begin();
  3. // какой-то код
  4. $pdo->commit();
  5. } catch (Exception $e) {
  6. // транзакцию откатим, а вот ошибку передадим дальше
  7. $pdo->rollback();
  8. throw $e;
  9. }


arimanecro пишет:
если при создании new PDO, у меня стоит перехватчик?

А тут-то не стоит. Почему ошибка должна перехватываться в какой-то другой try?


-----
PostgreSQL DBA
 
 Top
arimanecro
Отправлено: 08 Декабря, 2015 - 12:33:59
Post Id



Частый гость


Покинул форум
Сообщений всего: 209
Дата рег-ции: Май 2014  


Помог: 0 раз(а)




спс, за развернутый ответ.

Мелкий пишет:
А тут-то не стоит. Почему ошибка должна перехватываться в какой-то другой try?


хм, тогда получается, что любой запрос осуществляющийся с помощью ПДО, нужно постоянно ставить в try/catch ?

Др.словами, если ф-ия (например test) использует подключение ПДО из класса Db и внутри этой функции, ошибочный запрос, получается что ПДО-исключение выкидывается внутрь ф-ии test, а не к себе в класс Db?
 
 Top
Мелкий Супермодератор
Отправлено: 08 Декабря, 2015 - 12:49:16
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Для типичной политики обработки веб-запроса при получении ошибки запроса обычно лучшее что можно сделать - это быстренько свернуть всю работу, записать информацию в лог и показать пользователю красивую страницу ошибки.
Это всё-таки исключение, нетипичное поведение приложения.

И для этой типичной политики делается один корневой try, которым обёрнут практически весь проект. Он и будет ловить и ошибки подключения PDO, и ошибки запросов и всякие datetime, simplexml и что там ещё даже в нативном php5.x кидает исключения.
Практически все фреймворки через set_error_handler преобразуют все предупреждения кода в исключения.
Так что этот единственный catch отлавливает очень много чего происходящего в коде.

И только если вы хотите сделать какую-то отличающуюся обработку ошибок для отдельного фрагмента кода - то тогда этот кусок кода оборачиваете в свой отдельный try и пишется отдельная обработка.


-----
PostgreSQL DBA
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Вопросы новичков »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB