У меня конечно элементарный вопрос, но вот никак не могу понять принцип работы конструкции try-catch на php.
В общем имеем максимально простой код, как внизу.
Функция checkNum($number) проверяет является ли число больше или меньше 5.
Функция выполняется в блоке try.
Если в блоке try мы нарочно сделаем какую-то ошибку (например назовем функцию checkNNNums, которой не существует), то это по идее должно приводить к исключению и выполнению блока catch.
Действительно появляется ошибка, но код, который в блоке catch не срабатывает, т.е. например мы не видим заложенной в него надписи ‘Сработал блок Catch — Сообщение: ‘, а просто получаем
Fatal error: Uncaught Error: Call to undefined function checkNums()
Мне нужно отработать именно try-catch, понимаю, что есть варианты решения через альтернативные варианты, но нужно именно таким образом.
PHP 7.3
Код ниже:
<?php
function checkNum($number) {
if ($number>5) {
echo "число больше 5";
} else {
echo "число меньше 5";
}
}
try {
checkNum(7);
echo 'Сработал блок try';
}
catch(Exception $e) {
echo 'Сработал блок Catch - Сообщение: ' .$e->getMessage();
}
?>
I am trying to run this Example #1 from this page: http://php.net/manual/en/language.exceptions.php
<?php
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
return 1/$x;
}
try {
echo inverse(5) . "n";
echo inverse(0) . "n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "n";
}
// Continue execution
echo "Hello Worldn";
?>
However instead of the desired output I get:
0.2
Fatal error: Uncaught exception 'Exception' with message 'Division by zero.'
in xxx:
7 Stack trace: #0 xxx(14): inverse(0) #1 {main} thrown in xxx on line 7
The developer environment I am using is UniServer 3.5
with PHP 5.2.3
asked Jan 31, 2010 at 18:09
5
I just had this exact problem where it seemed like I had even copied the name of the exception and yet it didn’t catch it. It turned out it was my stupid mistake but I thought I should post my case here in case there is someone else in the same situation.
I had my exception in my namespace called A and the script was in a namespace called B. The problem was that I had AMyException which equals (in PHP) BAMyException (because my script is in the namespace called B!). All I had to do to fix it was to add backslash (or whatever it’s called) to the exception name so it would look like this: AMyException
answered Oct 25, 2011 at 16:56
PijusnPijusn
11k7 gold badges57 silver badges76 bronze badges
2
Quite old question, yet…
I had this problem as well (and that’s how I found this post) but just simple experiment allowed me to find the solution. Just try changing Exception
to Exception
. Worked for me!
EDIT:
As sivann pointed in the comments, using namespace should do the same thing. So simply put use Exception as Exception;
before your class declaration.
answered Dec 10, 2015 at 19:35
EnethionEnethion
1,1899 silver badges9 bronze badges
2
Try to put catch(Exception $e)
instead of catch(Exception $e)
. If you are using a code you don’t know about very well, or — especially — if you are using a framework, it might override the default PHP Exception with one of its own, and therefore you might go to the wrong path and get the undesired result. If you just put Exception
, then you are sure you are catching the base PHP exception.
answered Apr 20, 2017 at 8:52
0
You can not use the typical try{} catch{} blocks in PHP as you could do in another language like C# (Csharp).
If you do this:
try{
//division by zero
$number = 5/0;
}
catch(Exception $ex){
echo 'Got it!';
}
You will not see the ‘Got it!’ message never. Why? It’s just because PHP always needs an Exception to be «Thrown». You need to set your own error handler and throw an Exception with it.
See set_error_handler function: http://php.net/manual/es/function.set-error-handler.php
answered Oct 29, 2011 at 1:04
4
If you are using PHP 7, you may need Throwable instead of Exception
answered Mar 20, 2020 at 4:42
3
In my case, a weird situation occurred and catching Exception
didn’t work even when I had Exception
. Here is what to do to make sure that you never miss anything and always catch the error.
catch (Exception $e) {
// do what you want to do on exception catching
} catch (Throwable $e) {
// do what you want to do on exception catching
}
When you combine these two, you will never miss catching an Exception
. Make sure to put the before
Exception
and Throwable
. That’s important.
Edit
An efficient way to catch them would be this
catch (Exception|Throwable $e) {
// do what you want
}
This will catch that without you having two separate catch blocks
answered Oct 22, 2021 at 9:09
Koushik DasKoushik Das
9,3803 gold badges50 silver badges48 bronze badges
My initial though is you have a typo in the name of the exception you are catching/throwing, but if your code is exactly the same I’m not sure exactly what is going on.
Try the following modification of the original script, and paste your results. It will help diagnose your issue a bit better.
<?php
//set up exception handler to report what we didn't catch
function exception_handler($exception) {
if($exception instanceof MyException) {
echo "you didn't catch a myexception instancen";
} else if($exception instanceof Exception) {
echo "you didn't catch a exception instancen";
} else {
echo "uncaught exception of type: ".gettype($exception)."n";
}
echo "Uncaught exception: " , $exception->getMessage(), "n";
}
//install the handler
set_exception_handler('exception_handler');
class MyException extends Exception {
}
function inverse($x) {
if (!$x) {
throw new MyException('Division by zero.');
}
else return 1/$x;
}
try {
echo inverse(5) . "n";
echo inverse(0) . "n";
} catch (MyException $e) {
echo 'Caught myexception: ', $e->getMessage(), "n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "n";
}
// Continue execution
echo 'Hello World';
?>
answered Jan 31, 2010 at 23:11
sfrenchsfrench
9105 silver badges9 bronze badges
I had the same problem with following configurations,
PHP 5.2.14 (cli) (built: Aug 12 2010 17:32:30)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies
with eAccelerator v0.9.5.1, Copyright (c) 2004-2006 eAccelerator, by eAccelerator
The solution is to either disable eAccelerator or update it. I tried both and both of the fixes worked. The bug is reported here https://eaccelerator.net/ticket/242 (NB. firefox complains about their SSL cert) .
Now I am running try catch properly with following configurations,
PHP 5.2.4 (cli) (built: Oct 16 2007 09:13:35)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
with eAccelerator v0.9.6.1, Copyright (c) 2004-2010 eAccelerator, by eAccelerator
Darren Cook
27.5k13 gold badges114 silver badges215 bronze badges
answered Dec 20, 2010 at 8:17
YawarYawar
411 bronze badge
catch all exception in php
try
{
//place code
throw new Exception('foo');//eg
}
catch (Throwable $e)
{
dd('for php 7');
} catch (Exception $e)
{
dd('for php 5');
}
https://www.php.net/manual/en/language.exceptions.php
answered Mar 5, 2021 at 16:34
BalajiBalaji
9,2255 gold badges43 silver badges47 bronze badges
in Xdebug there is a setting:
xdebug.show_exception_trace = 1
This will force php to output exceptions even in a try catch block.
Turn this to 0
pearcoding
1,1491 gold badge9 silver badges28 bronze badges
answered Nov 3, 2013 at 16:48
2
TLDR; make sure you have use Exception;
on the top of both php files
answered Mar 25, 2020 at 14:26
Mr HeelisMr Heelis
2,3104 gold badges23 silver badges33 bronze badges
I am experiencing this as well. I read comment from Rowinson Gallego which state Exception must be thrown. So I modified my code from :
try
{
$number = 5/0; //or other exception
}
catch(Exception $e)
{
throw $e;
}
into :
try
{
$number = 5/0; //or other exception
}
catch(Exception $e)
{
throw new Exception($e->getMessage(),$e->getCode());
}
It works.
answered May 11, 2020 at 13:06
Again this old thread revisited…
I had not require_once’d the file containing my Exception subclass in the file with the try/catch block.
Somehow (maybe due to composer’s autoload) this didn’t result in a ‘cannot be resolved to a type’ error. And somehow my exception was being created with the expected namespace (in yet another file without the require_once). But it wasn’t caught. My directory structure does not match the namespaces so autoload might have loaded the correct class in the file with the try/catch but under a different namespace.
answered Mar 11, 2022 at 23:08
gladdgladd
375 bronze badges
Try to add a backslash before the class for example:
BEFORE
try {
if ($this->customerAuth->authenticate($customerId, $password)) {
$this->session->loginById($customerId);
}
} catch(MagentoFrameworkExceptionStateUserLockedException $e) {
return $this->respondWithCode('login', 401);
} catch (MagentoFrameworkExceptionInvalidEmailOrPasswordException $e) {
return $this->respondWithCode('login', 401);
}
AFTER
try {
if ($this->customerAuth->authenticate($customerId, $password)) {
$this->session->loginById($customerId);
}
} catch(MagentoFrameworkExceptionStateUserLockedException $e) {
return $this->respondWithCode('login', 401);
} catch (MagentoFrameworkExceptionInvalidEmailOrPasswordException $e) {
return $this->respondWithCode('login', 401);
}
answered Apr 4, 2022 at 12:10
BlackBlack
17.7k39 gold badges154 silver badges268 bronze badges
За последние 24 часа нас посетили 12245 программистов и 878 роботов. Сейчас ищут 582 программиста …
-
- С нами с:
- 26 фев 2012
- Сообщения:
- 2.198
- Симпатии:
- 184
Не понимаю, почему, если в блоке try будет ошибка, то cath не работает?
-
$userPath = mkdir(‘./userFile/’.$_SESSION[‘user’].‘/question/’ . $date . ‘/’ , 0700, true);
-
echo ‘<p>Произошла ошибка.</p>’ . $e->getMessage();
— Добавлено —
Вот так работает, но как сделать, что бы не показывало, саму ошибку?-
if(!$userPath = mkdir(‘./userFile/’.$_SESSION[‘user’].‘/question/’ . $date . ‘/’ , 0700, true)) {
-
throw new Exception(‘Ошибка.’);
-
echo ‘<p>Произошла ошибка.</p>’ . $e->getMessage();
-
- С нами с:
- 1 апр 2013
- Сообщения:
- 7.604
- Симпатии:
- 1.292
- Адрес:
- Лень
-
Команда форума
Модератор- С нами с:
- 20 июн 2012
- Сообщения:
- 8.522
- Симпатии:
- 1.744
Два вопроса. Версия php и какая ошибка
— Добавлено —
В седьмой ввели такую фитчу:
https://habrahabr.ru/post/261451/ -
- С нами с:
- 26 фев 2012
- Сообщения:
- 2.198
- Симпатии:
- 184
Warning: mkdir(): Not a directory
-
- С нами с:
- 1 апр 2013
- Сообщения:
- 7.604
- Симпатии:
- 1.292
- Адрес:
- Лень
верху скрипта
-
throw new ErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
catch (ErrorException $e) {
-
Команда форума
Модератор- С нами с:
- 18 мар 2010
- Сообщения:
- 32.415
- Симпатии:
- 1.768
попробуй ловить throwable
-
- С нами с:
- 26 фев 2012
- Сообщения:
- 2.198
- Симпатии:
- 184
Сделал обработку ошибок, на вставку в БД. Хороший ли вариант?
-
$sqlNewCity = «INSERT city (city_name) VALUES (:city)»;
-
if(!$newCityPrepare = $this->db->prepare($sqlNewCit)) {
-
if(!$newCityPrepare->bindValue(‘:city’, trim($newCity), PDO::PARAM_STR)) {
-
if(!$newCityPrepare->execute()) {
-
die(‘<p>Произошла неизвестная ошибка, повторите попытку или сообщите администратору.</p>’);
-
Команда форума
Модератор- С нами с:
- 20 июн 2012
- Сообщения:
- 8.522
- Симпатии:
- 1.744
PDO сам умеет исключениями бросаться при ошибках. http://phpfaq.ru/pdo#connect — там надо флаг указать PDO::ERRMODE_EXCEPTION
-
- С нами с:
- 26 фев 2012
- Сообщения:
- 2.198
- Симпатии:
- 184
Почему блок catch не срабатывает, если будет ошибка? Если биндить несуществующие переменные.
-
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
-
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
-
PDO::ATTR_EMULATE_PREPARES => false,
-
$pdo = new PDO($dsn, $user, $pass, $opt);
-
$sql = «INSERT INTO bookmark(`user_id`, `question_id`) VALUES(:userId, :questionId)»;
-
$bookmark = $pdo->prepare($sql);
-
$bookmark->bindValue(‘:userId’, trim($u), PDO::PARAM_INT);
-
$bookmark->bindValue(‘:questionId’, trim($q), PDO::PARAM_INT);
-
Команда форума
Модератор- С нами с:
- 20 июн 2012
- Сообщения:
- 8.522
- Симпатии:
- 1.744
Потому что это ошибка PHP, а не ошибка PDO. Должен был быть Notice
-
- С нами с:
- 26 фев 2012
- Сообщения:
- 2.198
- Симпатии:
- 184
нотису и показывает, как её можно обработать?
-
Команда форума
Модератор- С нами с:
- 20 июн 2012
- Сообщения:
- 8.522
- Симпатии:
- 1.744
-
- С нами с:
- 26 фев 2012
- Сообщения:
- 2.198
- Симпатии:
- 184
Ну это у пользователя шаг влево, шаг вправо и будет ошибка
-
Команда форума
Модератор- С нами с:
- 20 июн 2012
- Сообщения:
- 8.522
- Симпатии:
- 1.744
Пользователь тут при чём? Он что-ли пишет за тебя программу, и подставляет тебе несуществующие переменные? Есть способы ловить нотисыб set_error_handler, например, но в отлаженной программе такой ситуации просто не должно возникать
-
Команда форума
Модератор- С нами с:
- 18 мар 2010
- Сообщения:
- 32.415
- Симпатии:
- 1.768
в некоторых случаях нотис не отключить. Ловить надо throwable в php 7+
и то мне кажется я наталкивался на то, что всё равно нотис просачивался
-
- С нами с:
- 26 фев 2012
- Сообщения:
- 2.198
- Симпатии:
- 184
Я не понимаю, почему, если удалять папку, которой нету, то мою ошибку не выводит, а выводит Warning: rmdir?
-
function removeDirectory($dir) {
-
if ($objs = glob($dir.«/*»)) {
-
removeDirectory($delFolder);
-
die(‘Ошибка удаления ‘ . $e->getMessage());
-
Команда форума
Модератор- С нами с:
- 15 мар 2007
- Сообщения:
- 9.902
- Симпатии:
- 969
исключение не бросается вот и не ловится. при этом сама попытка удаления завершается неудачей на что пхп-машина выкидывает ворнинг.
есть идеи? -
Команда форума
Модератор- С нами с:
- 20 июн 2012
- Сообщения:
- 8.522
- Симпатии:
- 1.744
Warning не прерывает исполнение программы по дефолту, видимо по этому исключение не кидается. По стандартным функциям — надо смотреть в доках, бросают они исключения или нет (чаще всего не бросают, кстати). И если бросают, то в каких случаях
Linked 21 / 21 / 6 Регистрация: 12.12.2010 Сообщений: 677 |
||||
1 |
||||
28.03.2017, 14:56. Показов 3300. Ответов 9 Метки нет (Все метки)
Здравствуйте! Пытаюсь понять как работает try..catch..finnaly, вроде всё элементарно, но почему то не срабатывает у меня.. Вот код:
На выходе нужно что бы записалось сообщение ошибки, код ошибки, файл в котором ошибка и строка в файл с логами, а пользователю вывелось сообщение что произошёл сбой.. Но в итоге не получаю требуемого результата. PHP интепретатор ругается на 19 строку (finally), а если убераю — интерпретатор php выдаёт ошибку что я пытаюсь поделить на 0..
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
28.03.2017, 14:56 |
Ответы с готовыми решениями: Не работает try catch Try catch не работает Не работает Try-catch Не работает try/catch package lab_A3; 9 |
Jodah 3827 / 3178 / 1334 Регистрация: 01.08.2012 Сообщений: 10,768 |
||||
28.03.2017, 15:02 |
2 |
|||
PHP интепретатор ругается на 19 строку (finally) Работает начиная с PHP 5.5.
интерпретатор php выдаёт ошибку что я пытаюсь поделить на 0. Превращайте ошибки в исключения. Например так:
1 |
21 / 21 / 6 Регистрация: 12.12.2010 Сообщений: 677 |
|
28.03.2017, 15:20 [ТС] |
3 |
Jodah, с версией понятно, на OpenServer поменял — заработало. Но с второй частью я не понял. Я думал по идее, try отслеживается на наличие ошибок, и если в try какая-то ошибка — выполняется catch, который имеет сведения об ошибке, которыми я и могу манипулировать. Насчёт Вашего примера я не понял, в частности зачем функцию отдельно для всего этого создавать
0 |
120 / 116 / 77 Регистрация: 19.08.2013 Сообщений: 430 |
|
28.03.2017, 15:26 |
4 |
Я думал по идее, try отслеживается на наличие ошибок не ошибок а исключений, курите мануал
1 |
21 / 21 / 6 Регистрация: 12.12.2010 Сообщений: 677 |
|
28.03.2017, 15:43 [ТС] |
5 |
gbsoftware, я не курящий
0 |
3827 / 3178 / 1334 Регистрация: 01.08.2012 Сообщений: 10,768 |
|
28.03.2017, 16:21 |
6 |
Linked, ошибки и исключения — совершенно разные вещи. try-catch отлавливает только исключения. Если хотите отлавливать ошибки — нужно сначала трансформировать их в исключения.
1 |
21 / 21 / 6 Регистрация: 12.12.2010 Сообщений: 677 |
|
28.03.2017, 16:33 [ТС] |
7 |
Jodah, я понял о чём Вы. Ошибки они бывают разные, синтаксические и пр., а исключения — это например деление на 0, загрузка несуществующего файла и т.п.. Вот я рассматривал пример тот что я выше написал, но он не работает..Не хочется пока к другому примеру приходить, мне по своему курсу — надо с этим примером разобраться как работает..
0 |
Jodah 3827 / 3178 / 1334 Регистрация: 01.08.2012 Сообщений: 10,768 |
||||||||
28.03.2017, 16:52 |
8 |
|||||||
Сообщение было отмечено Linked как решение РешениеLinked, нет, я говорю не о концептуальных различиях, а о том, что для PHP ошибки и исключения — совершенно разные вещи. Вот исключение:
Вот ошибки:
Во втором примере на первой строчке ошибка уровня E_Notice, на второй — ошибка уровня E_Warning. Деление на ноль и include/require несуществующего файла — это ошибки. Не исключения. Практически все… как бы их назвать… ошибочные действия в PHP вызывают ошибки. Единственное, в PHP 7 большинство фатальных ошибок превращается в исключения. Также исключения могут выбрасывать различные библиотеки, например PDO (опционально).
1 |
21 / 21 / 6 Регистрация: 12.12.2010 Сообщений: 677 |
|
28.03.2017, 17:01 [ТС] |
9 |
Jodah, спасибо.. Надо разобраться с этим.. А то я в Москве на собеседованиях я совсем плавал..Надо повышать уровень знаний.
0 |
3827 / 3178 / 1334 Регистрация: 01.08.2012 Сообщений: 10,768 |
|
28.03.2017, 17:23 |
10 |
Накосячил с первым примером, там должно быть
1 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
28.03.2017, 17:23 |
10 |
Я пытаюсь запустить этот пример # 1 с этой страницы: http://php.net/manual/en/language.exceptions.php
У меня просто была эта точная проблема, когда мне показалось, что я даже скопировал название исключения, но все же не поймал его. Оказалось, что это была моя глупая ошибка, но я думал, что должен опубликовать свой случай здесь, если в той же ситуации есть кто-то другой.
У меня было мое исключение в моем пространстве имен под названием A, и скрипт находился в пространстве имен B. Проблема заключалась в том, что у меня было A MyException, которое равно (в PHP) B A MyException (потому что мой скрипт находится в пространстве имен B !). Все, что я должен был сделать, чтобы исправить это, заключалось в том, чтобы добавить к имени исключения обратную косую черту (или что-то еще), чтобы она выглядела так: A MyException
Довольно старый вопрос, но …
У меня тоже была эта проблема (и так я нашел этот пост), но простой эксперимент позволил мне найти решение. Просто попробуйте изменить Exception
в Exception
. Работал для меня!
РЕДАКТИРОВАТЬ:
Как указал Сиванн в комментариях, использование пространства имен должно делать то же самое. Поэтому просто use Exception as Exception;
перед объявлением класса.
Вы не можете использовать типичные блоки try {} catch {} в PHP, как вы могли бы сделать на другом языке, таком как C # (Csharp).
Если вы это сделаете:
try{ //division by zero $number = 5/0; } catch(Exception $ex){ echo 'Got it!'; }
Вы не увидите «Получил»! сообщение никогда. Зачем? Это просто потому, что PHP всегда нуждается в исключении, которое будет «Брошено». Вам нужно установить свой собственный обработчик ошибок и выбросить с ним исключение.
См. Функцию set_error_handler : http://php.net/manual/es/function.set-error-handler.php
Попробуйте поместить catch(Exception $e)
вместо catch(Exception $e)
. Если вы используете код, который вы не знаете об этом очень хорошо, или, особенно – если вы используете фреймворк, он может переопределить PHP Exception по умолчанию одним из своих, и, следовательно, вы можете пойти по неправильному пути и получить нежелательный результат. Если вы просто положили Exception
, тогда вы уверены, что поймаете базовое исключение PHP.
Вы не используете идентичный код, иначе исключение будет выбрано в строке 4 вместо 7. Какой код вы используете точно?
Мой первоначальный, хотя у вас есть опечатка во имя исключения, которое вы ловите / бросаете, но если ваш код точно такой же, я точно не знаю, что происходит.
Попробуйте выполнить следующую модификацию исходного сценария и вставьте свои результаты. Это поможет немного улучшить вашу проблему.
<?php //set up exception handler to report what we didn't catch function exception_handler($exception) { if($exception instanceof MyException) { echo "you didn't catch a myexception instancen"; } else if($exception instanceof Exception) { echo "you didn't catch a exception instancen"; } else { echo "uncaught exception of type: ".gettype($exception)."n"; } echo "Uncaught exception: " , $exception->getMessage(), "n"; } //install the handler set_exception_handler('exception_handler'); class MyException extends Exception { } function inverse($x) { if (!$x) { throw new MyException('Division by zero.'); } else return 1/$x; } try { echo inverse(5) . "n"; echo inverse(0) . "n"; } catch (MyException $e) { echo 'Caught myexception: ', $e->getMessage(), "n"; } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "n"; } // Continue execution echo 'Hello World'; ?>
У меня была та же проблема со следующими конфигурациями,
PHP 5.2.14 (cli) (построено: 12 августа 2010 г. 17:32:30) Copyright (c) 1997-2010 PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies с eAccelerator v0.9.5. 1 , Авторское право (c) 2004-2006 eAccelerator, by eAccelerator
Решение состоит в том, чтобы отключить eAccelerator или обновить его. Я попробовал оба, и оба исправления работали. Об ошибке сообщается здесь https://eaccelerator.net/ticket/242 (NB. Firefox жалуется на их сертификат SSL).
Теперь я запускаю try catch правильно со следующими конфигурациями,
PHP 5.2.4 (cli) (построено: 16 октября 2007 г. 09:13:35) Copyright (c) 1997-2007 PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies с eAccelerator v0.9.6. 1 , Авторское право (c) 2004-2010 eAccelerator, by eAccelerator
в Xdebug есть настройка:
xdebug.show_exception_trace = 1
Это заставит php выводить исключения даже в блок catch try. Поверните это на 0