Files
php-doc-ru/language/exceptions.xml
Alexander Moskaliov 6b79de02d3 Updated translation
git-svn-id: https://svn.php.net/repository/phpdoc/ru/trunk@316593 c90b9560-bf6c-de11-be94-00142212c4b1
2011-09-13 07:32:02 +00:00

362 lines
14 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 88a88985b966ce3acdc7835984636921e862e4c2 Maintainer: irker Status: ready -->
<!-- Reviewed: yes -->
<!-- $Revision$ -->
<chapter xml:id="language.exceptions" xmlns="http://docbook.org/ns/docbook">
<title>Исключения</title>
<para>
Модель исключений (exceptions) в PHP 5 проще, чем в других языках программирования.
Исключение можно сгенерировать (как говорят, "выбросить") при помощи оператора
<literal>throw</literal>, и можно перехватить (или, как говорят, "поймать")
оператором <literal>catch</literal>. Код генерирующий исключение, должен
быть окружен блоком <literal>try</literal>, для того чтобы можно было
перехватить исключение. Каждый блок <literal>try</literal>
должен иметь как минимум один соответствующий ему блок <literal>catch</literal>.
Так же можно использовать несколько блоков <literal>catch</literal>,
перехватывающих различные классы исключений.
Нормальное выполнение (когда не генерируются исключения в блоках
<literal>try</literal> или когда класс сгенерированного исключения не
совпадает с классами, объявленными в соответствующих блоках
<literal>catch</literal>) будет продолжено за последним блоком
<literal>catch</literal>. Исключения так же могут быть сгенерированы (или
вызваны еще раз) оператором <literal>throw</literal>
внутри блока <literal>catch</literal>.
</para>
<para>
При генерации исключения код следующий за оператором
<literal>throw</literal> исполнен не будет, а PHP предпримет попытку найти
первый блок <literal>catch</literal>, перехватывающий исключение данного
класса. Если исключение не будет перехвачено, PHP выдаст сообщение об
ошибке: "<literal>Uncaught Exception ...</literal>" (Неперехваченное
исключение), если не был определен обработчик ошибок при помощи
функции <function>set_exception_handler</function>.
</para>
<para>
Генерируемый объект должен принадлежать классу <classname>Exception</classname>
или наследоваться от <classname>Exception</classname>. Попытка сгенерировать
исключение другого класса приведет к неисправимой ошибке.
</para>
<note>
<para>
Внутренние функции PHP в основном используют
<link linkend="ini.error-reporting">сообщения об ошибках</link>, и только
новые <link linkend="language.oop5">объектно-ориентированные</link>
расширения используют исключения. Однако, ошибки можно легко преобразовать
в исключения с помощью класса <link linkend="class.errorexception">ErrorException</link>.
</para>
</note>
<tip>
<para>
<link linkend="intro.spl">Стандартная библиотека PHP (SPL)</link> предоставляет
хороший набор <link linkend="spl.exceptions">встроенных классов исключений</link>.
</para>
</tip>
<example>
<title>Выброс исключений</title>
<programlisting role="php">
<![CDATA[
<?php
function inverse($x) {
if (!$x) {
throw new Exception('Деление на ноль.');
}
else return 1/$x;
}
try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Выброшено исключение: ', $e->getMessage(), "\n";
}
// Продолжение выполнения
echo 'Hello World';
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
0.2
Выброшено исключение: Деление на ноль.
Hello World
]]>
</screen>
</example>
<example>
<title>Вложенные исключения</title>
<programlisting role="php">
<![CDATA[
<?php
class MyException extends Exception { }
class Test {
public function testing() {
try {
try {
throw new MyException('foo!');
} catch (MyException $e) {
/* повторный выброс исключения */
throw $e;
}
} catch (Exception $e) {
var_dump($e->getMessage());
}
}
}
$foo = new Test;
$foo->testing();
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
string(4) "foo!"
]]>
</screen>
</example>
<sect1 xml:id="language.exceptions.extending">
<title>Наследование исключений</title>
<para>
Определенный пользователем класс исключения должен быть определен, как
класс расширяющий (наследующий) встроенный класс Exception. Ниже приведены методы и
свойства класса Exception, доступные дочерним классам.
</para>
<example>
<title>Встроеный класс Exception</title>
<programlisting role="php">
<![CDATA[
<?php
class Exception
{
protected $message = 'Unknown exception'; // Сообшение
private $string; // Свойство для __toString
protected $code = 0; // Код исключения,
// определяемый пользователем
protected $file; // Файл в котором было
// выброшено исключение
protected $line; // Строка в которой было
// выброшено исключение
private $trace; // Трассировка вызовов методов и функций
private $previous; // Предыдущее исключение, для
// вложенных блоков try
public function __construct($message = null, $code = 0, Exception $previous = null);
final private function __clone(); // Запрещает клонировать исключения
final public function getMessage(); // Возвращает сообшение исключения
final public function getCode(); // Код исключения
final public function getFile(); // Файл, где выброшено исключение
final public function getLine(); // Строка, выбросившая исключени
final public function getTrace(); // Массив backtrace()
final public function getTraceAsString(); // Трассировка вызовов как строка
/* Переопределяемое */
public function __toString(); // форматированная строка для отображения
}
?>
]]>
</programlisting>
</example>
<para>
Если класс, наследуемый от Exception переопределяет <link
linkend="language.oop5.decon">конструктор</link>, необходимо вызвать в
конструкторе <link linkend="language.oop5.paamayim-nekudotayim"
>parent::__construct()</link>, чтобы быть уверенным, что все дынные
будут доступны. Метод <link linkend="language.oop5.magic">__toString()</link>
может быть переопределен, что бы обеспечить нужный вывод, когда объект
преобразуется в строку.
</para>
<note>
<para>
Исключения нельзя клонировать. Попытка <link
linkend="language.oop5.cloning">клонировать</link> исключение приведет
к неисправимой ошибке <constant>E_ERROR</constant>.
</para>
</note>
<example>
<title>Наследование класса Exception (PHP 5.3.0+)</title>
<programlisting role="php">
<![CDATA[
<?php
/**
* Определим свой класс исключения
*/
class MyException extends Exception
{
// Переопределим исключение так, что параметр message станет обязательным
public function __construct($message, $code = 0, Exception $previous = null) {
// некоторый код
// убедитесь, что все передаваемые параметры верны
parent::__construct($message, $code, $previous);
}
// Переопределим строковое представление объекта.
public function __toString() {
return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
}
public function customFunction() {
echo "Мы можем определять новые методы в наследуемом классе\n";
}
}
/**
* Создадим класс для тестирования исключения
*/
class TestException
{
public $var;
const THROW_NONE = 0;
const THROW_CUSTOM = 1;
const THROW_DEFAULT = 2;
function __construct($avalue = self::THROW_NONE) {
switch ($avalue) {
case self::THROW_CUSTOM:
// Бросаем собственное исключение
throw new MyException('1 - неправильный параметр', 5);
break;
case self::THROW_DEFAULT:
// Бросаем встроеное исключение
throw new Exception('2 - недопустимый параметр', 6);
break;
default:
// Никаких исключений, объект будет создан.
$this->var = $avalue;
break;
}
}
}
// Example 1
try {
$o = new TestException(TestException::THROW_CUSTOM);
} catch (MyException $e) { // Will be caught
echo "Поймано собственное переопределенное исключение\n", $e;
$e->customFunction();
} catch (Exception $e) { // Будет пропущено.
echo "Поймано встроенное исключение\n", $e;
}
// Отсюда будет продолжено выполнение программы
var_dump($o); // Null
echo "\n\n";
// Example 2
try {
$o = new TestException(TestException::THROW_DEFAULT);
} catch (MyException $e) { // Тип исключения не совпадет
echo "Поймано переопределенное исключение\n", $e;
$e->customFunction();
} catch (Exception $e) { // Будет перехвачено
echo "Перехвачено встроенное исключение\n", $e;
}
// Отсюда будет продолжено выполнение программы
var_dump($o); // Null
echo "\n\n";
// Example 3
try {
$o = new TestException(TestException::THROW_CUSTOM);
} catch (Exception $e) { // Будет перехвачено.
echo "Поймано встроенное исключение\n", $e;
}
// Продолжение исполнения программы
var_dump($o); // Null
echo "\n\n";
// Example 4
try {
$o = new TestException();
} catch (Exception $e) { // Будет пропущено, т.к. исключение не выбрасывается
echo "Поймано встроенное исключение\n", $e;
}
// Продолжение выполнения программы
var_dump($o); // TestException
echo "\n\n";
?>
]]>
</programlisting>
<note>
<para>
PHP 5 до версии 5.3.0 не поддерживает вложенные исключения.
Если есть необходимость запустить вышеприведенный пример в указанных версиях PHP,
то нужно заменить класс MyException.
</para>
<programlisting role="php">
<![CDATA[
<?php
/**
* Определим свой класс исключения
*/
class MyException extends Exception
{
// Переопределим исключение так, что параметр message станет обязательным
public function __construct($message, $code = 0) {
// некоторый код
// убедитесь, что все передаваемые параметры верны
parent::__construct($message, $code);
}
// Переопределим строковое представление объекта.
public function __toString() {
return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
}
public function customFunction() {
echo "Мы можем определять новые методы в наследуемом классе\n";
}
}
?>
]]>
</programlisting>
</note>
</example>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->