Я использую следующий скрипт для использования базы данных с помощью PHP:
try{ $db = new PDO('mysql:host='.$host.';port='.$port.';dbname='.$db, $user, $pass, $options); } catch(Exception $e){ $GLOBALS['errors'][] = $e; }
Теперь я хочу использовать этот дескриптор базы данных для выполнения запроса с помощью этого кода:
try{ $query = $db->prepare("INSERT INTO users (...) VALUES (...);"); $query->execute(array( '...' => $..., '...' => $... )); } catch(Exception $e){ $GLOBALS['errors'][] = $e; }
Вот проблема:
$GLOBALS['errors'][]
и скрипт все еще работает после этого, Примечание. Неопределенная переменная: db в C: \ xampp \ htdocs […] \ test.php в строке 32
Неустранимая ошибка: вызовите функцию-член prepare () для не-объекта в C: \ xampp \ htdocs […] \ test.php в строке 32
Примечание. Строка 32 – это команда $query = $db->prepare(...)
.
То есть, сценарий падает, а try / catch кажется бесполезным. Вы знаете, почему эта вторая попытка / уловка не работает и как ее решить?
Спасибо за помощь!
EDIT: Есть действительно хорошие ответы. Я подтвердил то, что не совсем то, что я хотел сделать, но это, вероятно, лучший подход.
try
/ catch
блоки работают только для сброшенных исключений ( throw Exception
или подкласс Exception
). Вы не можете поймать фатальные ошибки, используя try
/ catch
.
Если ваше соединение с БД не может быть установлено, я считаю его фатальным, так как вам, вероятно, нужна ваша БД, чтобы сделать что-либо значимое на странице.
PDO
выдает исключение, если соединение не может быть установлено. Ваша конкретная проблема заключается в том, что $db
не определяется при попытке вызвать метод с ним, чтобы вы получили нулевой указатель (сорт), который является фатальным. Вместо того, чтобы перепрыгивать, if ($db == null)
обручи, как предлагают другие, вы должны просто исправить свой код, чтобы убедиться, что $db
либо всегда определяется, когда вам это нужно, либо имеет менее хрупкий способ убедиться, что соединение с БД доступен в коде, который его использует.
Если вы действительно хотите «уловить» фатальные ошибки, используйте set_error_handler
, но это все еще останавливает выполнение сценария при фатальных ошибках.
Если соединение с базой данных завершается неудачно, $db
с первой try .. catch
блокирует try .. catch
. Вот почему позже вы не можете использовать член не-объекта, в вашем случае $db->prepare(...)
. Перед использованием этого добавить
if ($db) { // other try catch statement }
Это гарантирует, что у вас есть экземпляр db для работы с ним.
Почему вы используете try ... catch
заявления для объявления этого. Замените это:
try{ $db = new PDO('mysql:host='.$host.';port='.$port.';dbname='.$db, $user, $pass, $options); }
С:
$db = new PDO('mysql:host='.$host.';port='.$port.';dbname='.$db, $user, $pass, $options) or die("Cannot Create PDO!");
Или на вашем пути:
$db = new PDO('mysql:host='.$host.';port='.$port.';dbname='.$db, $user, $pass, $options) or ($GLOBALS['errors'][] = "Cannot Create PDO!");
Попробуйте добавить следующую инструкцию if:
if ($db) { $query = $db->prepare("INSERT INTO users (...) VALUES (...);"); $query->execute(....); } else die('Connection lost');
try{ if(!is_null($db)) { $query = $db->prepare("INSERT INTO users (...) VALUES (...);"); $query->execute(array( '...' => $..., '...' => $... )); } } catch(Exception $e){ $GLOBALS['errors'][] = $e; }