PHP

call в php - Генерирование и перехват событий в php

В модели ООП при возникновении ошибки создается и генерируется (throw) исключение. Это означает, что при генерировании исключения во время выполнения сценария оно будет постоянно передаваться в стек вызовов до тех пор, пока не произойдет одно из следующих событий:

Исключение будет перехвачено одной из функций в стеке.
Исключение не будет перехвачено и достигнет вершины стека.

Генерирование исключения в сценарии осуществляется с помощью оператора throw и передачи ему экземпляра генерируемого исключения, как показано в листинге 13.26.

Листинг 13.26. Генерирование исключения

<? php  
class ThrowExample { 
 
	public function makeError() { 
	throw new Exception("Пример исключения"); 
	} 
 
} 
 
$inst = new ThrowExample(); 
$inst->makeError(); 
?>


В листинге 13.26 во время выполнения метода makeError() генерируется исключение, передаваемое в стек вызовов, который в данном случае является одноуровневым
стеком. Поскольку для перехвата этого исключения нет соответствующей логики, возникнет ошибка и произойдет останов сценария:

Fatal error : Uncaught exception 'exception' with message 'This is an example Exception' in /listing_13_26.php:4
Неисправимая ошибка: Неперехваченное исключение 'exception' с сообщением

'Пример исключения' в /listing_13_26.php:4
Stack trace:
#0 /listing_13_26.php(8): ThrowExample->makeError()
#1 {main}

318

thrown in /listing_13_26.php on line 4

Как видите, исключения формируют гораздо более информативные сообщения об ошибках, чем доступные в версии PHP 4. Однако даже с учетом такой степени информативности лучше всего исправлять ошибки незаметно для пользователя. Чтобы сделать это с помощью исключений, используйте новую конструкцию PHP 5 — блок try/catch.
Блок try/catch служит для выполнения сегмента кода, который может генерировать исключение и вернуться к выполнению кода. Синтаксис блока try/catch выглядит следующим образом:


try  { 
 
	/* код для выполнения */ 
 
}   
catch (ExceptionClass $variable) { 
 
	/* Код для перехвата исключения */ 
 
}  
[ catch (AnotherException $variable) { 
 
} ] ...


Обратите внимание, что ExceptionClass и $variable — это просто заполнители. На
самом деле ExceptionClass может быть выражен любым классом, унаследованным от
класса Exception . Если в PHP-сценарии используется блок try/catch , будут выполнены
следующие действия:

1. Выполняется код в части try блока .
2. Если в блоке try не было обнаружено ни одного исключения, выполнение сценария продолжается за пределами блока try.
3. Если возникло исключение, класс исключения сравнивается с исключениями, которые были перехвачены в блоке try.

4. Если блок try перехватывает сгенерированное исключение, выполняется код в блоке catch, в котором была перехвачена ошибка.

5. Если блок try не перехватывает исключение, оно помещается в стек вызовов.

При перехвате исключения сгенерированный объект исключения присваивается переменной, имя которой указано в блоке перехвата (в предыдущем синтаксисе — переменная $variable).
В завершение анализа исключений рассмотрим код в листинге 13.27, основанный на примере из листинга 13.26.

Листинг 13.27. Перехват исключений в PHP 5

<?php 
class MyException extends Exception { 
 
	/* Никакого другого нового кода не нужно, 
	просто новый тип исключения */ 
 
} 
class AnotherException extends Exception { 
 
	/* Класс оболочки для определения другого 
	типа исключения */ 
 
} 
class ThrowExample { 
 
	public function makeMyException() { 
	throw new MyException(); 
 
} 
 
public function makeAnotherException() { 
 
	throw new AnotherException(); 
 
} 
public function makeError() { 
 
	throw new Exception(); 
 
} 
 
} 
 
 
$inst = new ThrowExample(); 
try { 
 
	$inst->makeMyException(); 
 
} catch(MyException $e) { 
 
	echo "Перехвачено 'MyException'\n"; 
 
} 
try { 
 
	$inst->makeAnotherException(); 
 
} catch(MyException $e) { 
 
	echo "Перехвачено 'MyException'\n"; 
 
} catch(AnotherException $e) { 
 
	echo "Caught 'AnotherException'\n"; 
 
} 
try { 
 
	$inst->makeError(); 
 
}  
catch(MyException $e) { 
 
	echo "Перехвачено 'MyException'\n"; 
 
} catch(AnotherException $e) { 
 
	echo "Перехвачено 'AnotherException'\n"; 
 
}


Несмотря на большой объем кода, в листинге 13.27 представлено несколько примеров использования блоков try/catch вместе с исключениями. В этом примере создан простой класс ThrowExample, который генерирует три разновидности класса Exception: собственно класс Exception, класс MyException и класс AnotherException. Затем создается экземпляр класса ThrowExample и генерируются все три исключения, используя три отдельных блока try/catch. При выполнении этого сценария выполняется код в блоке try, генерирующий исключение с типом MyException. Поскольку это исключение перехватывается в блоке try вызова функции, выполняется код в блоке catch. Во втором блоке try процесс повторяется, но на этот раз генерируется исключение AnotherException.

В этом случае определены два типа исключений, которые будут перехватываться, поэтому оба исключения сравниваются со сгенерированным исключением. Так как блок try действительно перехватывает исключение AnotherException, то выполняется его блок catch . Для третьего блока try генерируется исключение, которое не перехватывается ни одним из блоков catch. Хотя класс Exception является родительским классом по отношению к классам MyException и AnotherException, он не является таким же специфическим классом, поэтому соответствие не может быть установлено и исключение передается в сценарий, что приводит к возникновению ошибки, останавливающей выполнение сценария. Если выполнить код из листинга 13.27, будет сгенерирован следующий вывод:

Перехвачено 'MyException'


Перехвачено 'AnotherException'
Fatal error: Uncaught exception 'exception' in /exp.php:18
Stack trace:
#0 /exp.php(39): ThrowExample->makeError()
#1 {main}
thrown in /exp.php on line 18


Как и можно было предположить, первые два исключения перехватываются соответствующими блоками try, и выполнение сценария продолжается. Однако выполнение
сценария прекращается после вызова метода makeError(), поскольку при этом генерируется исключение, которое нельзя перехватить.

Исключения подчиняются иерархии объектов, как и любой другой класс в PHP. Следовательно, вы можете перехватить любое сгенерированное исключение с помощью следующего блока try/catch:

 try  { 
/* Некоторый код */ 
}  catch (Exception $e) { 
/* Вызывается при генерировании исключения */ 
}


Поскольку все исключения наследуют внутренний класс Exception в PHP, то перехват самого класса Exception в результате приведет к перехвату любого генерируемого исключения.

Исключения являются невероятно мощным инструментом для программиста, использующего объектно-ориентированную модель. Однако использовать их необходимо
всегда очень осторожно! Не следует полагаться на исключения как на способ управления выполнен
Теги:
call, перехват событий
Добавлено: 16 Апреля 2018 20:35:25 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...