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>