У меня есть скрипт php, который позволяет во время выполнения скриптов вызывать исключение. Я хочу, чтобы мой PHP возобновлялся с того места, где он остановился (где он исключил исключение).
Должен ли я помещать тот же код выполнения в «catch» часть кода?
Например, можно сказать, что подключается к mySQL, он терпит неудачу для выключения соединения
function someCode(){ $pdostmt = $this->prepare($this->sql); if($pdostmt->execute($this->bind) !== false) { if(preg_match("/^(" . implode("|", array("select", "describe", "pragma")) . ") /i", $this->sql)) return $pdostmt->fetchAll($this->fetchOption); elseif(preg_match("/^(" . implode("|", array("delete", "insert", "update")) . ") /i", $this->sql)) return $pdostmt->rowCount(); } try { someCode(); } } catch (PDOException $e) { //re-execute same code as within the try clause? someCode(); }
Прежде всего, нужно четко указать, что исключение является только фатальным, если оно не поймано . Захват исключения не останавливает выполнение скрипта. Он просто останавливает фрейм стека в блоке try и передает управление блоку catch. Оттуда ваш скрипт будет продолжать выполняться как обычно.
Вылавливая исключение, мы все равно продолжаем нормальное выполнение скрипта после того, как исключение поймано …
try { echo "Try...\n"; throw new Exception("This is an exception"); } catch(Exception $e) { echo "Exception caught with message: " . $e->getMessage() . "\n"; } echo "Script is still running...";
Вы можете захотеть обработчик исключений . Чтобы использовать обработчик исключений, чтобы вам не приходилось обрабатывать каждое исключение в блоках try
/ catch
вы можете сделать следующее …
function myExceptionHandler($e) { echo "Uncaught exception with message: " , $e->getMessage(), "\n"; } set_exception_handler('myExceptionHandler'); // Registers the exception handler throw new Exception("This is Exception 1"); throw new Exception("This is Exception 2"); throw new Exception("This is Exception 3"); echo "The script is still running...";
Изменить: после выяснения вашего вопроса, я думаю, что я должен указать, что вы хотите, не обработчик исключений, но на самом деле вы вообще не хотите использовать Исключения. То, что вы пытаетесь сделать, не требует выброса исключений вообще. Не помещайте PDO в режим исключения, если то, что вы намереваетесь делать, просто обрабатывает такую ошибку. Исключение следует использовать только для устранения исключительных ошибок. Весь смысл исключения состоит в том, чтобы убедиться, что вы выполняете свое обещание. Например, если ваша функция обещает, что она всегда вернет объект PDOStatement, и есть случай, когда он не может этого сделать, тогда имеет смысл выбросить исключение. Это позволяет зрителю узнать, что мы достигли точки, где мы не можем сдержать наше обещание.
Что вы хотите – это базовая обработка ошибок …
function someCode(){ $pdostmt = $this->prepare($this->sql); if($pdostmt->execute($this->bind) !== false) { if(preg_match("/^(" . implode("|", array("select", "describe", "pragma")) . ") /i", $this->sql)) return $pdostmt->fetchAll($this->fetchOption); elseif(preg_match("/^(" . implode("|", array("delete", "insert", "update")) . ") /i", $this->sql)) return $pdostmt->rowCount(); } else { return false; } } while (someCode() === false) { /* Call someCode() until you get what you want */ }
Используйте php 4/5 register_shutdown_function.
Doc здесь: http://php.net/manual/en/function.register-shutdown-function.php
Я собираюсь предположить, что вы не можете обработать исключение в функции, которую она бросает. Если вы хотите возобновить свое исключение, вам необходимо обработать исключение. Все остальное – плохое кодирование, приводящее к путанице для вас или любого другого, кто работает над проектом. Мы исключаем исключение, поднимаясь по дереву, потому что мы не можем справиться с ними в своей функции из-за проблем с областью.
Что касается вашего примера, который я буду расширять. Вы говорите, что операция не может продолжаться, потому что соединение не может произойти. На самом деле мы не хотим явно повторять функцию, потому что мы по существу создадим постоянную попытку подключения, поэтому мы используем блок catch выше дерева, где мы можем уведомить пользователя и заставить их решить, что мы хотим сделать , При этом мы можем использовать блоки catch в правильных местах для сохранения данных, чтобы мы могли восстановить данные и выполнить их позже. На самом деле мы хотим завершить работу до точки перед блоком try.
Это даст вам более четкий путь выполнения. Иногда вам нужно переосмыслить функцию / метод, чтобы он делал одно и то, что правильно.
Чтобы ответить на ваш вопрос просто и грубо. Нет, его плохая идея назвать функцию try (ed) в блоке catch, и простая причина заключается в том, что у вас уже нет блока try, чтобы поймать там исключение. Исключения создают более значимую обработку ошибок, а затем передают true и false как возврат. Тем не менее, это означает, что вам нужно обойти весь круг в их обработке.
Теперь для альтернативного примера … Скажем, у нас есть несколько серверов, к которым мы можем подключиться, и вы хотели запустить мысли, которые вы бы поставили try / catch внутри цикла, и catch будет проверять это исключение и делать какие-либо очистки до выполняя следующий цикл. Если произойдет какое-либо другое исключение, мы (re) выставим исключение. Правильный способ добиться того, что вы ищете, будет таким.
function someCode() { $pdostmt = $this->prepare($this->sql); while($status == false) { try { $status = $pdostmt->execute($this->bind) } catch (PDOException $e) { if($e->getMessage("What ever the error message is") { //Fix it here } else { throw $e; } } } //Do other stuff return $data; //or true/false }
Возможно, вы сможете использовать окончательную часть catch try, если вы не получите исключение при выполнении.
try { // some crashing code } catch (Exception $e) { //some catch code } finally { //code that will run anyways. }