Ошибки расширения PDO -- перехват исключения для fetch()

Интересует вопрос - какие именно виды ошибок включают в себя ошибки типа PDOException?

Пример из учебника Котерова(стр 709):

<?php #Вывод содержимого таблицы catalogs
require_once('connect_dbPHP7.php');

    $query = "SELECT * FROM catalogs";
    $cat = $pdo->query($query);
try{
    while($catalog = $cat->fetch())
        echo $catalog['cname'] . "<br/>";
} catch (PDOException $e){
    echo "Ошибка выполнения запроса: " . $e->getMessage();
}

?>

Я пытался (самыми разными способами) специально вызвать блок кода после инструкции catch, но мне это так и не удалось - выводится просто информация об ошибке без сопроводительного текста. Как я понял, ошибки вида PDOException это ошибки именно выполнения запросов, а значит, в книге опечатка и инструкция try должна располагаться хотя бы перед инициализацией переменной $cat. Тем более что далее в книге буквально через несколько страниц изображен как раз такой вариант:

<?php #Вывод содержимого таблицы catalogs
require_once('connect_dbPHP7.php');
try{
    $query = "SELECT * FROM catalogs";
    $cat = $pdo->query($query);
    $catalogs = $cat->fetchAll();
    foreach($catalogs as $catalog)
        echo $catalog['cname'] . "<br/>";
} catch (PDOException $e){
    echo "Ошибка выполнения запроса: " . $e->getMessage();
}

?>   

Объясните, пожалуйста, прав я или нет? То есть, опечатка ли в листинге или я чего-то не понял?

Key Words for FKN + antitotal forum (CS VSU):

vedro-compota's picture

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

Но всё же: как именно вы понимаете работу вызова fetch(), откуда извлекаются данные?

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

Есть способ проверить, может ли фетч бросить исключение вообще после удачного завершения запроса.
напишите что-то вроде:

require_once('connect_dbPHP7.php');
 
$query = "SELECT * FROM catalogs";
$cat = $pdo->query($query);
echo ('запрос выполнен');
sleep(5); 
try{
    while($catalog = $cat->fetch()) {
        echo $catalog['cname'] . "<br/>";
        sleep(10); // 10 секунд паузы на каждый виток

}
} catch (PDOException $e){
    echo "Ошибка выполнения запроса: " . $e->getMessage();
}
 
?>

и выключите СУБД в после выполнения запрос ->query()
(сам запрос выполнится моментально, а вот дальше скрипт искусственно замедлен. так что можно давать команду на выключения через секунду после запуска скрипта).

Главная мысль: фетч может упасть как минимум в ситуации, когда отвалится соедние с БД (а такое на практике бывает).

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

какие именно виды ошибок включают в себя ошибки типа PDOException?

Это просто класс исключения (вы тоже можете созавать собственные классы исключения), который бросает расширение PDO, это ошибки связанные с работой этого расширения --

  • падения соединения с базой
  • ошибка запроса
  • разные ограничения на работу с СУБД и т.д.

_____________
матфак вгу и остальная классика =)

Voronve's picture

Никак не выходит выключить СУБД отдельно от open server. Как только выключаю, тут же выдается команда, что open server будет перезагружен. И браузер выдает сообщение - "Не удается получить доступ к сайту". А как из него выйти из командной строки тоже без понятия - в списке команд такой не значится.

какой командой выключаешь?

Собственно, не командой, а примерно вот так:
screen

В пункте MySQL/MariaDB Выбираю самый верхний пункт - "не использовать". По другому не знаю как... Пробовал через терминал:
cmd

Но не нашел там функции, отключающей mySQL (exit и quit просто выходят из терминала)

vedro-compota's picture

по-идее можно глянуть в диспетчере задач windows -- и оттуда отстрелить процесс с именем "mysql".

_____________
матфак вгу и остальная классика =)

Voronve's picture

Вариант с диспетчером задач оказался успешным! Результаты эксперимента:
1. Даже после отключения mySQL через диспетчер задач, запрос успешно выполняется и выводится в браузер. Следовательно, данные предварительно были записаны в драйвер PDO, так?
2. При повторном запуске того-же скрипта данные больше не выводятся а выводится сообщение о невозможности подключения к базе данных, следовательно она действительно была отключена.
3. Из двух предыдущих пунктов следует, что конструкция типа:

try{
    while($catalog = $cat->fetch())
        echo $catalog['cname'] . "<br/>";
        sleep(10); // 10 секунд паузы на каждый виток
} catch (PDOException $e){
    echo "Ошибка выполнения запроса: " . $e->getMessage();
} 

не имеет смысла т.к. исключения типа PDOException не будут генерится на данном участке кода вообще. Я прав?