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
Форумы портала PHP.SU :: Версия для печати :: try...catch Ошибки и Исключения
Форумы портала PHP.SU » » Вопросы новичков » try...catch Ошибки и Исключения

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

1. Hapson - 09 Марта, 2014 - 13:27:17 - перейти к сообщению
Всем привет!
Читал мануал, но что-то никак не отдуплю - что такое исключения, и чем они отличаются от ошибок?
Ну вот к примеру такой код:
PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3. if($_SERVER['REQUEST_METHOD'] == 'POST'){
  4.         try{
  5.                 $email = $_POST['email'];
  6.                 $password = $_POST['password'];
  7.         }catch(Exception $e){
  8.                 // переадресация на форму входа
  9.                 // и вывод ошибки пользователю
  10.         }
  11.         // ...
  12. }
  13. ?>
  14.  

Ситуация такая: юзер открывает firebug, удаляет поле password и отправляет форму.
Я наивно полагал, что сработает блок catch, так как в массиве $_POST не будет поля password. Однако получил Notice и не попал в catch.

Отсюда вопрос: что такое исключение и как перехватить ошибки в блоке try?
2. OrmaJever - 09 Марта, 2014 - 13:43:29 - перейти к сообщению
пользу исключений не показать на примере "Hello World", что бы понять их принцип нужно много кода.
Вкратце: исключения сделаны для того что бы избежать цепную реакцию, то есть когда в коде произошла ошибка, вы кидаете исключение и весь код от throw до catch выполнятся не будет, тем самым избавляя вас от кучи ошибок.
3. Hapson - 09 Марта, 2014 - 13:54:29 - перейти к сообщению
OrmaJever пишет:
то есть когда в коде произошла ошибка, вы кидаете исключение

Ну вот ошибка и произошла, но catch не сработал, так как он не реагирует на ошибки.
Это что получается, код должен выглядеть так:
PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3. if($_SERVER['REQUEST_METHOD'] == 'POST'){
  4.         try{
  5.                 if(!isset($_POST['email'])){
  6.                         throw new Exception(/* ... */);
  7.                 }else{
  8.                         $email = $_POST['email'];
  9.                 }
  10.                 if(!isset($_POST['password'])){
  11.                         throw new Exception(/* ... */);
  12.                 }else{
  13.                         $email = $_POST['password'];
  14.                 }
  15.         }catch(Exception $e){
  16.                 // переадресация на форму входа
  17.                 // и вывод ошибки пользователю
  18.         }
  19.         // ...
  20. }
  21. ?>
  22.  


Не понимаю...
Или чтобы ловить ошибки нужно писать свой обработчик ошибок и уже в нем обрабатывать ошибку, а затем вызывать throw new ErrorException() ?
4. OrmaJever - 09 Марта, 2014 - 14:05:02 - перейти к сообщению
Hapson пишет:
Ну вот ошибка и произошла, но catch не сработал, так как он не реагирует на ошибки.

Да, я тоже считаю что перед тем как показывать notice или warning, ядро должно кинуть исключение, но разработчики мои мысли видимо читать не умеют Огорчение
Hapson пишет:
Это что получается, код должен выглядеть так:

да, в большинстве случаев интерпретатор не знает где по вашем ошибка, он же не знает что когда пустой $_POST['email'] то это ошибка. Поэтому исключения нужно кидать самому.
А отличаются от простых if() {} else {} в том что их можно пробрасывать через не ограниченную вложенность, например.
PHP:
скопировать код в буфер обмена
  1. function a($p) {
  2.   if($p == 1) throw new Exception(1);
  3.   elseif($p == 2) throw new Exception(2);
  4.   return 'abc';
  5. }
  6.  
  7. function b() {
  8.   for($i=0; $<3; ++$i)
  9.      echo a($num);
  10. }
  11.  
  12. try{
  13.   b();
  14. } catch(Exception $e) { ... }


А ещё плюс в том что исключения могут быть разных типов и у них могут быть разные обработчики.
5. Hapson - 09 Марта, 2014 - 14:06:47 - перейти к сообщению
Кажись понял, нужно как-то так делать:
PHP:
скопировать код в буфер обмена
  1.  
  2. function ErrorToException($errNo, $errStr, $errFile, $errLine){
  3.         $message = <<<MESS
  4. <div style="background-color:#fff; margin: 10px; padding: 10px; border: 1px solid #000; border-radius: 5px;">
  5. Error: $errStr
  6. File: $errFile
  7. Line: $errLine
  8. </div>
  9. MESS;
  10.         echo $message;
  11.         throw new ErrorException($errStr, $errNo, 0, $errFile, $errLine);
  12. }
  13.  
  14. set_error_handler("ErrorToException");
  15.  

Прикольно Улыбка
6. OrmaJever - 09 Марта, 2014 - 14:08:02 - перейти к сообщению
Hapson пишет:
Кажись понял, нужно как-то так делать:

нет, set_error_handler устанавливает пользовательский обработчик именно ошибок, а не исключений. исключения != ошибки.
7. Hapson - 09 Марта, 2014 - 14:13:43 - перейти к сообщению
OrmaJever пишет:
set_error_handler устанавливает пользовательский обработчик именно ошибок

А в пользовательском обработчике ошибок мы помимо обработки ошибки кидаем исключение:

Таким образом можно по своему обрабатывать ошибки, а также ловить их в блоках try
http://www.php.net/manual/ru/cla...rorexception.php
(Добавление)
То есть по сути ошибки становятся исключениями, но и ошибками не перестают быть...
как-то так
8. OrmaJever - 09 Марта, 2014 - 14:17:20 - перейти к сообщению
а как вы ловить его собрались? Однако
9. Hapson - 09 Марта, 2014 - 14:23:30 - перейти к сообщению
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. if($_SERVER['REQUEST_METHOD'] == 'POST'){
  3.         try{
  4.                 $email = $_POST['email'];
  5.                 $password = $_POST['password'];
  6.         }catch(ErrorException $e){
  7.                 var_dump($e);
  8.         }
  9. }
  10. ?>


Если в $_POST чего-то нет, то возникнет Notice, сработает мой обработчик ошибки, в котором бросается исключение, которое можно поймать в catch, если оно нужно конечно.
А можно просто сделать что нужно, например вывести юзеру ошибку.
Короче при ошибках в try сработает catch
10. OrmaJever - 09 Марта, 2014 - 14:29:03 - перейти к сообщению
Hapson пишет:
Если в $_POST чего-то нет, то возникнет Notice, сработает мой обработчик ошибки, в котором бросается исключение, которое можно поймать в catch, если оно нужно конечно.

снимаю шляпу Здорово Стыдно конечно, но я о таком подумать не мог Растерялся
(Добавление)
Я думаю эта информация даже изменила мою php'шную жизнь)))
11. Hapson - 09 Марта, 2014 - 14:35:14 - перейти к сообщению
[quote=OrmaJever][/quote]
Да, удобно, но злоупотреблять наверное не стоит.
Конечно если код работает без ошибок, то все ОК. Но если ошибки есть, то каждая ошибка будет генерировать исключение, что накладно.
(Добавление)
И если есть @ в коде, то их сразу отсеивать в обработчике через error_reporting()
12. OrmaJever - 09 Марта, 2014 - 19:27:33 - перейти к сообщению
Hapson классный подход вы подсказали.
PHP:
скопировать код в буфер обмена
  1. class NoticeError extends ErrorException {}
  2. class WarningError extends ErrorException {}
  3. class StrictError extends ErrorException {}
  4. class DeprecatedError extends ErrorException {}
  5. $error_handler = function($code, $mess, $file, $line) {
  6.         $err = array(E_WARNING=>'WarningError', E_NOTICE=>'NoticeError', E_STRICT=>'StrictError', E_DEPRECATED=>'DeprecatedError');
  7.         throw new $err[$code]($mess, 0, 1, $file, $line);      
  8. };
  9. set_error_handler($error_handler, E_NOTICE | E_WARNING | E_DEPRECATED | E_STRICT);
  10.  
  11. try {
  12.         $dasdas;
  13. } catch(NoticeError $e) { echo $e->getLine();}

Есть единственный минус, если убрать блок try catch то будет фатал об не пойманом исключении, что немного обидно.
13. DelphinPRO - 09 Марта, 2014 - 19:42:03 - перейти к сообщению
а я через error_handler перехватываю ошибки, а потом кучно списком вывожу в конце страницы, чтобы верстку не ломать, и на headers send by... не нарваться Улыбка
Кидать исключение, по моему, перебор Улыбка
14. Ch_chov - 09 Марта, 2014 - 19:49:31 - перейти к сообщению
OrmaJever пишет:
если убрать блок try catch то будет фатал об не пойманом исключении, что немного обидно.

Можно задать exception handler.
http://www.php.net/manual/en/fun...tion-handler.php
15. OrmaJever - 09 Марта, 2014 - 20:00:19 - перейти к сообщению
Ch_chov пишет:
Можно задать exception handler.

да да да да!!!! спасибо!))) Я сегодня почти получил свою мечту по фитчам в php Браво

 

Powered by ExBB FM 1.0 RC1