com doc/zh: Sync with en: language/exceptions.xml
[email protected] (Dai Jie) Thu, 31 Dec 2020 08:35:33 +0000
| Newsgroups | php.doc.zh |
|---|---|
| Message-ID | <[email protected]> |
Commit: a81a5e395bd89933ae782d15a6c7e47820968a23 Author: daijie <[email protected]> Thu, 31 Dec 2020 16:35:33 +0800 Parents: 30c6dd3c899bfeb9941a3ad871cdb8c78b87489f Branches: master Link: http://git.php.net/?p=doc/zh.git;a=commitdiff;h=a81a5e395bd89933ae782d15a6c7e47820968a23 Log: Sync with en Changed paths: M language/exceptions.xml
diff_a81a5e395bd89933ae782d15a6c7e47820968a23.txt
(text/plain, 11.8 KB)
diff --git a/language/exceptions.xml b/language/exceptions.xml
index 159dab55..aab4d391 100644
--- a/language/exceptions.xml
+++ b/language/exceptions.xml
@@ -1,10 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
+<!-- EN-Revision: 351652 Maintainer: daijie Status: ready -->
+
<chapter xml:id="language.exceptions" xmlns="http://docbook.org/ns/docbook">
<title>异常处理</title>
<sect1 xml:id="language.exceptions.extending">
- <title>扩展(extend) PHP 内置的异常处理类</title>
+ <title>扩展(extend) 异常处理类</title>
<para>
用户可以用自定义的异常处理类来扩展 PHP
内置的异常处理类。以下的代码说明了在内置的异常处理类中,哪些属性和方法在子类中是可访问和可继承的。译者注:以下这段代码只为说明内置异常处理类的结构,它并不是一段有实际意义的可用代码。
@@ -14,7 +16,7 @@
<programlisting role="php">
<![CDATA[
<?php
-class Exception
+class Exception extends Throwable
{
protected $message = 'Unknown exception'; // 异常信息
private $string; // __toString cache
@@ -47,7 +49,7 @@ class 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>
@@ -57,7 +59,7 @@ class Exception
</para>
</note>
<example>
- <title>扩展 PHP 内置的异常处理类 (PHP 5.3.0+)</title>
+ <title>扩展 PHP 内置的异常处理类</title>
<programlisting role="php">
<![CDATA[
<?php
@@ -137,7 +139,6 @@ echo "\n\n";
try {
$o = new TestException(TestException::THROW_DEFAULT);
} catch (MyException $e) { // 不能匹配异常的种类,被忽略
-
echo "Caught my exception\n", $e;
$e->customFunction();
} catch (Exception $e) { // 捕获异常
@@ -174,68 +175,52 @@ echo "\n\n";
?>
]]>
</programlisting>
- <note>
- <para>
- Versions of PHP 5, prior to PHP 5.3.0 do not support nesting of exceptions.
- The following code fragment can be used as a replacement MyException class
- if you wish to run this example.
- </para>
- <programlisting role="php">
-<![CDATA[
-<?php
-/**
- * Define a custom exception class
- */
-class MyException extends Exception
-{
- // Redefine the exception so message isn't optional
- public function __construct($message, $code = 0) {
- // some code
-
- // make sure everything is assigned properly
- parent::__construct($message, $code);
- }
-
- // custom string representation of object
- public function __toString() {
- return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
- }
-
- public function customFunction() {
- echo "A custom function for this type of exception\n";
- }
-}
-?>
-]]>
- </programlisting>
- </note>
</example>
</sect1>
<simplesect xml:id="language.exceptions.introduction">
<para>
- PHP 5 has an exception model similar to that of other programming
- languages. An exception can be &throw;n, and caught ("&catch;ed") within
- PHP. Code may be surrounded in a &try; block, to facilitate the catching
- of potential exceptions. Each &try; must have at least one corresponding
- &catch; or &finally; block.
+ PHP 有一个和其他语言相似的异常模型。
+ 在 PHP 里可以 &throw; 并 &catch; 异常。
+ 为了捕获潜在的异常,可以将代码包含在 &try; 块里。
+ 每个 &try; 都必须有一个相应的
+ &catch; 或 &finally; 代码块。
</para>
-
<para>
- The thrown object must be an instance of the
- <classname>Exception</classname> class or a subclass of
- <classname>Exception</classname>. Trying to throw an object that is not
- will result in a PHP Fatal Error.
+ 如果抛出异常的函数范围内没有 &catch; 块,异常会沿调用栈“向上冒泡”,
+ 直到找到匹配的 &catch; 块。
+ 沿途会执行所有遇到的 &finally; 块。
+ 在没有设置全局异常处理程序(exception handler)时,
+ 如果调用栈向上都没有遇到匹配的 &catch;,程序会抛出 fatal 错误并终止执行。
</para>
+ <para>
+ 抛出的对象必须是 <classname>Exception</classname> 自身或
+ <classname>Exception</classname>的子类。
+ 抛出其他对象会导致 PHP 报 Fatal 错误。
+ </para>
+ <para>
+ PHP 8.0.0 起,&throw; 关键词现在开始是一个表达式,可用于任何表达式的场景。
+ 在此之前,它是一个语句,必须独占一行。
+ </para>
+
</simplesect>
<simplesect xml:id="language.exceptions.catch">
<title><literal>catch</literal></title>
<para>
+ A &catch; block defines how to respond to a thrown exception. A &catch;
+ block defines one or more types of exception or error it can handle, and
+ optionally a variable to which to assign the exception. (The variable was
+ required prior to PHP 8.0.0.) The first &catch; block a thrown exception
+ or error encounters that matches the type of the thrown object will handle
+ the object.
+ </para>
+ <para>
Multiple &catch; blocks can be used to catch different classes of
exceptions. Normal execution (when no exception is thrown within the &try;
block) will continue after that last &catch; block defined in sequence.
- Exceptions can be &throw;n (or re-thrown) within a &catch; block.
+ Exceptions can be &throw;n (or re-thrown) within a &catch; block. If not,
+ execution will continue after the &catch; block that was triggered.
</para>
<para>
When an exception is thrown, code following the statement will not be
@@ -244,19 +229,49 @@ class MyException extends Exception
"<literal>Uncaught Exception ...</literal>" message, unless a handler has
been defined with <function>set_exception_handler</function>.
</para>
+ <para>
+ As of PHP 7.1.0, a &catch; block may specify multiple exceptions
+ using the pipe (<literal>|</literal>) character. This is useful for when
+ different exceptions from different class hierarchies are handled the
+ same.
+ </para>
+ <para>
+ As of PHP 8.0.0, the variable name for a caught exception is optional.
+ If not specified, the &catch; block will still execute but will not
+ have access to the thrown object.
+ </para>
</simplesect>
<simplesect xml:id="language.exceptions.finally">
<title><literal>finally</literal></title>
<para>
- In PHP 5.5 and later, a &finally; block may also be specified after or
+ A &finally; block may also be specified after or
instead of &catch; blocks. Code within the &finally; block will always be
executed after the &try; and &catch; blocks, regardless of whether an
exception has been thrown, and before normal execution resumes.
</para>
+ <para>
+ One notable interaction is between the &finally; block and a &return; statement.
+ If a &return; statement is encountered inside either the &try; or the &catch; blocks,
+ the &finally; block will still be executed. Moreover, the &return; statement is
+ evaluated when encountered, but the result will be returned after the &finally; block
+ is executed. Additionally, if the &finally; block also contains a &return; statement,
+ the value from the &finally; block is returned.
+ </para>
</simplesect>
- <simplesect xml:id="language.exceptions.notes">
+ <simplesect xml:id="language.exceptions.exception-handler">
+ <title><literal>Global exception handler</literal></title>
+ <para>
+ If an exception is allowed to bubble up to the global scope, it may be caught
+ by a global exception handler if set. The <function>set_exception_handler</function>
+ function can set a function that will be called in place of a &catch; block if no
+ other block is invoked. The effect is essentially the same as if the entire program
+ were wrapped in a &try;-&catch; block with that function as the &catch;.
+ </para>
+ </simplesect>
+
+ <simplesect xml:id="language.exceptions.notes">
&reftitle.notes;
<note>
@@ -264,9 +279,24 @@ class MyException extends Exception
Internal PHP functions mainly use
<link linkend="ini.error-reporting">Error reporting</link>, only modern
<link linkend="language.oop5">Object oriented</link>
- extensions use exceptions. However, errors can be simply translated to
+ extensions use exceptions. However, errors can be easily translated to
exceptions with <link linkend="class.errorexception">ErrorException</link>.
+ This technique only works with non-fatal errors, however.
</para>
+ <example>
+ <title>Converting error reporting to exceptions</title>
+ <programlisting role="php">
+<![CDATA[
+<?php
+function exceptions_error_handler($severity, $message, $filename, $lineno) {
+ throw new ErrorException($message, 0, $severity, $filename, $lineno);
+}
+
+set_error_handler('exceptions_error_handler');
+?>
+]]>
+ </programlisting>
+ </example>
</note>
<tip>
<para>
@@ -314,7 +344,7 @@ Hello World
</screen>
</example>
<example>
- <title>Exception handling with a <literal>finally</literal> block</title>
+ <title>Exception handling with a &finally; block</title>
<programlisting role="php">
<![CDATA[
<?php
@@ -358,6 +388,33 @@ Hello World
</screen>
</example>
<example>
+ <title>Interaction between the &finally; block and &return;</title>
+ <programlisting role="php">
+<![CDATA[
+<?php
+
+function test() {
+ try {
+ throw new Exception('foo');
+ } catch (Exception $e) {
+ return 'catch';
+ } finally {
+ return 'finally';
+ }
+}
+
+echo test();
+?>
+]]>
+ </programlisting>
+ &example.outputs;
+ <screen>
+<![CDATA[
+finally
+]]>
+ </screen>
+ </example>
+ <example>
<title>Nested Exception</title>
<programlisting role="php">
<![CDATA[
@@ -393,6 +450,83 @@ string(4) "foo!"
]]>
</screen>
</example>
+ <example>
+ <title>Multi catch exception handling</title>
+ <programlisting role="php">
+<![CDATA[
+<?php
+
+class MyException extends Exception { }
+
+class MyOtherException extends Exception { }
+
+class Test {
+ public function testing() {
+ try {
+ throw new MyException();
+ } catch (MyException | MyOtherException $e) {
+ var_dump(get_class($e));
+ }
+ }
+}
+
+$foo = new Test;
+$foo->testing();
+
+?>
+]]>
+ </programlisting>
+ &example.outputs;
+ <screen>
+<![CDATA[
+string(11) "MyException"
+]]>
+ </screen>
+ </example>
+ <example>
+ <title>Omitting the caught variable</title>
+ <para>Only permitted in PHP 8.0.0 and later.</para>
+ <programlisting role="php">
+<![CDATA[
+<?php
+
+class SpecificException extends Exception {}
+
+function test() {
+ throw new SpecificException('Oopsie');
+}
+
+try {
+ test();
+} catch (SpecificException) {
+ print "A SpecificException was thrown, but we don't care about the details.";
+}
+?>
+]]>
+ </programlisting>
+ </example>
+ <example>
+ <title>Throw as an expression</title>
+ <para>Only permitted in PHP 8.0.0 and later.</para>
+ <programlisting role="php">
+<![CDATA[
+<?php
+
+class SpecificException extends Exception {}
+
+function test() {
+ do_something_risky() or throw new Exception('It did not work');
+}
+
+try {
+ test();
+} catch (Exception $e) {
+ print $e->getMessage();
+}
+?>
+]]>
+ </programlisting>
+ </example>
</simplesect>
</chapter>