svn: /phpdoc/ru/trunk/language/ control-structures/match.xml exceptions.xml types/declarations.xml

[email protected] (Andrey Gromov) Thu, 26 Nov 2020 11:53:26 +0000
Newsgroups php.doc.ru
Message-ID <[email protected]>
rjhdby                                   Thu, 26 Nov 2020 11:53:26 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=351668

Log:
new

Changed paths:
    A   phpdoc/ru/trunk/language/control-structures/match.xml
    U   phpdoc/ru/trunk/language/exceptions.xml
    A   phpdoc/ru/trunk/language/types/declarations.xml
svn-diffs-351668.txt (text/x-diff, 47.2 KB)
Added: phpdoc/ru/trunk/language/control-structures/match.xml
===================================================================
--- phpdoc/ru/trunk/language/control-structures/match.xml	                        (rev 0)
+++ phpdoc/ru/trunk/language/control-structures/match.xml	2020-11-26 11:53:26 UTC (rev 351668)
@@ -0,0 +1,278 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- $Revision$ -->
+<!-- EN-Revision: 351515 Maintainer: rjhdby Status: ready -->
+<!-- Reviewed: no -->
+
+<sect1 xml:id="control-structures.match" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <title><literal>match</literal></title>
+ <?phpdoc print-version-for="match"?>
+ <para>
+  Выражение <literal>match</literal> предназначено для ветвления потока исполнения на
+  основании проверки совпадения значения с заданным условием.
+  Аналогично оператору <literal>switch</literal>, выражение
+  <literal>match</literal> принимает на вход выражение, которое сравнивается
+  с множеством альтернатив. Но, в отличии от <literal>switch</literal>,
+  оно обрабатывает значение в стиле, больше похожем на тернарный оператор.
+  Также, в отличии от <literal>switch</literal>, используется строгое сравнение
+  (<code>===</code>), а не слабое (<code>==</code>).
+  Выражение match доступно начиная с PHP 8.0.0.
+ </para>
+
+ <example>
+  <title>Структура выражения <literal>match</literal></title>
+  <programlisting role="php">
+<![CDATA[
+<?php
+$return_value = match (subject_expression) {
+    single_conditional_expression => return_expression,
+    conditional_expression1, conditional_expression2 => return_expression,
+};
+?>
+]]>
+  </programlisting>
+
+  <note>
+   <simpara>
+    Результат <literal>match</literal> использовать не обязательно.
+   </simpara>
+  </note>
+  <note>
+   <simpara>
+    Выражение <literal>match</literal> <emphasis>должно</emphasis> завершаться
+    точкой с запятой <literal>;</literal>.
+   </simpara>
+  </note>
+ </example>
+
+ <para>
+  Выражение <literal>match</literal> похоже на оператор
+  <literal>switch</literal> за исключением некоторых ключевых отличий:
+
+  <itemizedlist>
+   <listitem>
+    <simpara>
+     В отличии от switch, в <literal>match</literal> используется строгое сравнение (<code>===</code>).
+    </simpara>
+   </listitem>
+   <listitem>
+    <simpara>
+     Выражение <literal>match</literal> возвращает результат.
+    </simpara>
+   </listitem>
+   <listitem>
+    <simpara>
+     В <literal>Match</literal> исполняется только одна, первая подошедшая, ветвь кода, тогда как
+     в <literal>switch</literal> происходит сквозное исполнение начиная с подошедшего условия и
+     до первого встретившегося оператора <literal>brake</literal>.
+    </simpara>
+   </listitem>
+   <listitem>
+    <simpara>
+     Выражение <literal>match</literal> должно быть исчерпывающим.
+    </simpara>
+   </listitem>
+  </itemizedlist>
+ </para>
+
+ <para>
+  Также как и оператор <literal>switch</literal>, <literal>match</literal>
+  последовательно проводит проверки на совпадение с заданными условиями.
+  Выполнения кода условий происходит лениво, т.е. код следующего условия выполняется только
+  если все предыдущие проверки провалились. И выполнено будет только одна ветвь кода,
+  соответствующая подошедшему условию.
+  пример:
+  <informalexample>
+   <programlisting role="php">
+<![CDATA[
+<?php
+$result = match ($x) {
+    foo() => ...,
+    $this->bar() => ..., // bar() не будет выполнен, если foo() === $x
+    $this->baz => beep(), // beep() будет выполнен только если $x === $this->baz
+    // etc.
+};
+?>
+]]>
+   </programlisting>
+  </informalexample>
+ </para>
+
+ <para>
+  Условия в <literal>match</literal> могут быть множественными. В этом случае их следует разделять запятыми.
+  Множественные условия работают по принципу логического ИЛИ и, по сути, являются
+  сокращённой формой для случаев, когда несколько условий должны обрабатываться идентично.
+ </para>
+ <para>
+  <informalexample>
+   <programlisting role="php">
+<![CDATA[
+<?php
+$result = match ($x) {
+    // Множественное условие:
+    $a, $b, $c => 5,
+    // Аналогично трём одиночным:
+    $a => 5,
+    $b => 5,
+    $c => 5,
+};
+?>
+]]>
+   </programlisting>
+  </informalexample>
+ </para>
+ <para>
+  Также можно использовать шаблон <literal>default</literal>.
+  Этот шаблон совпадает с чем угодно, для чего не нашлось совпадений раньше.
+  К примеру:
+  <informalexample>
+   <programlisting role="php">
+<![CDATA[
+<?php
+$expressionResult = match ($condition) {
+    1, 2 => foo(),
+    3, 4 => bar(),
+    default => baz(),
+};
+?>
+]]>
+   </programlisting>
+  </informalexample>
+  <note>
+   <simpara>
+    Использование нескольких шаблонов default приведет к фатальной ошибке
+    <constant>E_FATAL_ERROR</constant>.
+   </simpara>
+  </note>
+ </para>
+
+ <para>
+  Выражение <literal>match</literal> должно быть исчерпывающим. Если
+  проверяемое выражение не совпало ни с одним из условий, то будет
+  выброшено исключение <classname>UnhandledMatchError</classname>.
+ </para>
+
+ <example>
+  <title>Пример не обрабтанного выраженияо</title>
+  <programlisting role="php">
+<![CDATA[
+<?php
+$condition = 5;
+
+try {
+    match ($condition) {
+        1, 2 => foo(),
+        3, 4 => bar(),
+    };
+} catch (\UnhandledMatchError $e) {
+    var_dump($e);
+}
+?>
+]]>
+  </programlisting>
+  &example.outputs;
+  <screen>
+<![CDATA[
+object(UnhandledMatchError)#1 (7) {
+  ["message":protected]=>
+  string(33) "Unhandled match value of type int"
+  ["string":"Error":private]=>
+  string(0) ""
+  ["code":protected]=>
+  int(0)
+  ["file":protected]=>
+  string(9) "/in/ICgGK"
+  ["line":protected]=>
+  int(6)
+  ["trace":"Error":private]=>
+  array(0) {
+  }
+  ["previous":"Error":private]=>
+  NULL
+}
+]]>
+  </screen>
+ </example>
+
+ <sect2>
+  <title>Использование match для проверки сложных условий</title>
+  <para>
+   Выражение <literal>match</literal> можно использовать не только для проверки идентичности,
+   но и для любых выражений возвращающих логическое значение. В этом случае в качестве входного
+   параметра передаётся выражение <code>true</code>.
+  </para>
+
+  <example>
+   <title>Использование match для ветвления в зависимости от вхождения в диапазоны целых чисел</title>
+   <programlisting role="php">
+<![CDATA[
+<?php
+
+$age = 23;
+
+$result = match (true) {
+    $age >= 65 => 'пожилой',
+    $age >= 25 => 'взрослый',
+    $age >= 18 => 'совершеннолетний',
+    default => 'ребёнок',
+}
+
+var_dump($result);
+?>
+]]>
+   </programlisting>
+   &example.outputs;
+   <screen>
+<![CDATA[
+string(11) "совершеннолетний"
+]]>
+   </screen>
+  </example>
+
+  <example>
+   <title>Использование match для ветвления в зависимости от содержимого строки</title>
+   <programlisting role="php">
+<![CDATA[
+<?php
+
+$text = 'Bienvenue chez nous';
+
+$result = match (true) {
+    str_contains($text, 'Welcome') || str_contains($text, 'Hello') => 'en',
+    str_contains($text, 'Bienvenue') || str_contains($text, 'Bonjour') => 'fr',
+    // ...
+};
+
+var_dump($result);
+?>
+]]>
+   </programlisting>
+   &example.outputs;
+   <screen>
+<![CDATA[
+string(2) "fr"
+]]>
+   </screen>
+  </example>
+ </sect2>
+</sect1>
+
+<!-- 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
+-->


Property changes on: phpdoc/ru/trunk/language/control-structures/match.xml
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
\ No newline at end of property
Modified: phpdoc/ru/trunk/language/exceptions.xml
===================================================================
--- phpdoc/ru/trunk/language/exceptions.xml	2020-11-26 10:55:52 UTC (rev 351667)
+++ phpdoc/ru/trunk/language/exceptions.xml	2020-11-26 11:53:26 UTC (rev 351668)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- EN-Revision: 351112  Maintainer: irker Status: ready -->
+<!-- EN-Revision: 351652  Maintainer: irker Status: ready -->
 <!-- Reviewed: yes -->
 <!-- $Revision$ -->
 <chapter xml:id="language.exceptions" xmlns="http://docbook.org/ns/docbook">
@@ -192,21 +192,41 @@
    перехватить исключение. Каждый блок &try;
    должен иметь как минимум один соответствующий ему блок &catch; или &finally;.
   </para>
-
   <para>
+   В случае, если выброшено исключение, для которого нет блока &catch; в текущей функции,
+   это исключение будет "всплывать" по стеку вызова, пока не будет найден
+   подходящий блок &catch;. При этом, все встреченные блоки &finally; бдут исполнены.
+   Если стек вызовов раскрутится до глобальной области видимости, не встретив подходящего
+   блока &catch;, программа завершит работу с фатальной ошибкой, если только у вас
+   не настроен глобальный обработчик исключений.
+  </para>
+  <para>
    Генерируемый объект должен принадлежать классу <classname>Exception</classname>
    или наследоваться от <classname>Exception</classname>. Попытка сгенерировать
    исключение другого класса приведет к фатальной ошибке PHP.
   </para>
+  <para>
+   Начиная с PHP 8.0.0, ключевое слово &throw; является выражением и может использоваться
+   в контексте других выражений. В более ранних версиях оно являлось оператором и требовало
+   размещения в отдельной строке.
+  </para>
  </simplesect>

  <simplesect xml:id="language.exceptions.catch">
   <title><literal>catch</literal></title>
   <para>
+   Блок &catch; определяет то, как следует реагировать на выброшенное исключение.
+   В блоке &catch; указывается один или более типов исключений или ошибок(Error), которые он
+   будет обрабатывать. Также указывается и переменная, которой будет присвоено
+   пойманное исключение (начиная с PHP 8.0.0 задавать эту переменную не обязательно).
+   Выброшенное исключение или ошибка будут обработаны первым подходящим блоком &catch;.
+  </para>
+  <para>
    Можно использовать несколько блоков &catch;, перехватывающих различные классы
    исключений. Нормальное выполнение (когда не генерируются исключения в блоках
    &try;) будет продолжено за последним блоком &catch;. Исключения могут быть
    сгенерированы (или вызваны еще раз) оператором &throw; внутри блока &catch;.
+   Если нет, то исполнение будет продолжено после отработки блока &catch;.
   </para>
   <para>
    При генерации исключения код, следующий после описываемого выражения,
@@ -218,10 +238,15 @@
    функции <function>set_exception_handler</function>.
   </para>
   <para>
-   В PHP 7.1 и выше, блок &catch; может принимать несколько типов исключений с помощью
-   символа (<literal>|</literal>). Это полезно, когда разные исключения из разных иерархий классов
-   обрабатываются одинаково.
+   Начиная с PHP 7.1.0, блок &catch; может принимать несколько типов исключений с помощью
+   символа (<literal>|</literal>). Это полезно, когда разные исключения из разных
+   иерархий классов обрабатываются одинаково.
   </para>
+  <para>
+   Начиная с PHP 8.0.0, задание переменной для пойманного исключения опционально.
+   Если она не задана, блок &catch; будет исполняться, но не будет иметь доступа
+   к объекту исключения.
+  </para>
  </simplesect>

  <simplesect xml:id="language.exceptions.finally">
@@ -240,6 +265,18 @@
   </para>
  </simplesect>

+ <simplesect xml:id="language.exceptions.exception-handler">
+  <title><literal>Глобальный обработчик исключений</literal></title>
+  <para>
+   Если исключение дошло по стеку вызовов до глобальной области видимости, оно может быть
+   обработано глобальным обработчиком исключений, если он задан.
+   С помощью функции <function>set_exception_handler</function> можно задать функцию,
+   которая будет выполнена вместо блока &catch;, если не нашлось подходящего. Эффект
+   аналогичен тому, как будто мы всю нашу программу обернули в блок &try;-&catch;, где
+   за реализацию блока &catch; отвечает установленная функция.
+  </para>
+ </simplesect>
+
  <simplesect xml:id="language.exceptions.notes">
   &reftitle.notes;

@@ -250,7 +287,22 @@
     новые <link linkend="language.oop5">объектно-ориентированные</link>
     расширения используют исключения. Однако, ошибки можно легко преобразовать
     в исключения с помощью класса <link linkend="class.errorexception">ErrorException</link>.
+    Однако это не сработает для фатальных ошибок.
    </para>
+   <example>
+    <title>Преобразование сообщения об ошибках в исключение</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>
@@ -328,9 +380,9 @@
 echo "Привет, мир\n";
 ?>
 ]]>
-    </programlisting>
-    &example.outputs;
-    <screen>
+   </programlisting>
+   &example.outputs;
+   <screen>
 <![CDATA[
 0.2
 Первый блок finally.
@@ -338,11 +390,11 @@
 Второй блок finally.
 Привет, мир
 ]]>
-    </screen>
+   </screen>
   </example>
   <example>
-    <title>Взаимодействие между блоками &finally; и &return;</title>
-    <programlisting role="php">
+   <title>Взаимодействие между блоками &finally; и &return;</title>
+   <programlisting role="php">
 <![CDATA[
 <?php

@@ -359,14 +411,14 @@
 echo test();
 ?>
 ]]>
-    </programlisting>
-    &example.outputs;
-    <screen>
+   </programlisting>
+   &example.outputs;
+   <screen>
 <![CDATA[
 finally
 ]]>
-    </screen>
-   </example>
+   </screen>
+  </example>
   <example>
    <title>Вложенные исключения</title>
    <programlisting role="php">
@@ -395,13 +447,13 @@

 ?>
 ]]>
-    </programlisting>
-    &example.outputs;
-    <screen>
+   </programlisting>
+   &example.outputs;
+   <screen>
 <![CDATA[
 string(4) "foo!"
 ]]>
-    </screen>
+   </screen>
   </example>
   <example>
    <title>Обработка нескольких исключений в одном блоке catch</title>
@@ -428,14 +480,58 @@

 ?>
 ]]>
-    </programlisting>
-    &example.outputs;
-    <screen>
+   </programlisting>
+   &example.outputs;
+   <screen>
 <![CDATA[
 string(11) "MyException"
 ]]>
-    </screen>
+   </screen>
   </example>
+  <example>
+   <title>Пример блока &catch; без указания переменной</title>
+   <para>Допустимо начиная с PHP 8.0.0</para>
+   <programlisting role="php">
+<![CDATA[
+<?php
+
+class SpecificException extends Exception {}
+
+function test() {
+    throw new SpecificException('Ой!');
+}
+
+try {
+    test();
+} catch (SpecificException) {
+    print "Было поймано исключение SpecificException, но нам безразлично, что у него внутри.";
+}
+?>
+]]>
+   </programlisting>
+  </example>
+  <example>
+   <title>Throw как выражение</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('Всё сломалось');
+}
+
+try {
+    test();
+} catch (Exception $e) {
+    print $e->getMessage();
+}
+?>
+]]>
+   </programlisting>
+  </example>
  </simplesect>

 </chapter>

Added: phpdoc/ru/trunk/language/types/declarations.xml
===================================================================
--- phpdoc/ru/trunk/language/types/declarations.xml	                        (rev 0)
+++ phpdoc/ru/trunk/language/types/declarations.xml	2020-11-26 11:53:26 UTC (rev 351668)
@@ -0,0 +1,803 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- $Revision$ -->
+<!-- EN-Revision: 351382 Maintainer: rjhdby Status: ready -->
+<!-- Reviewed: no -->
+
+<sect1 xml:id="language.types.declarations">
+ <title>Объявление типов</title>
+
+ <para>
+  Объявления типов могут использоваться для аргументов функций, возвращаемых значений и,
+  начиная с PHP 7.4.0, для свойств класса. Они используются во время исполнения для проверки,
+  что значение имеет точно тот тип, который для них указан. В противном случае будет выброшено
+  исключение <classname>TypeError</classname>.
+ </para>
+
+ <!-- Find better place where to put this note -->
+ <note>
+  <!-- TODO Link to covariance section -->
+  <para>
+   При переопределении родительского метода, тип возвращаемого значения дочернего метода должен
+   соответствовать любому объявлению возвращаемого типа родительского. Если в родительском
+   методе тип возвращаемого значения не объявлен, то это можно  сделать в дочернем.
+  </para>
+ </note>
+
+ <sect2 xml:id="language.types.declarations.base">
+  <title>Одиночные типы</title>
+  <informaltable>
+   <tgroup cols="3">
+    <thead>
+     <row>
+      <entry>&Type;</entry>
+      <entry>&Description;</entry>
+      <entry>&Version;</entry>
+     </row>
+    </thead>
+    <tbody>
+     <row>
+      <entry>Имя класса/интерфейса</entry>
+      <entry>
+       Значение должно представлять собой &instanceof; заданного класса или интерфейса.
+      </entry>
+      <entry></entry>
+     </row>
+     <row>
+      <entry><type>self</type></entry>
+      <entry>
+       Значение должно представлять собой &instanceof; того же класса, в котором определён метод.
+       Может использоваться только в классах.
+      </entry>
+      <entry></entry>
+     </row>
+     <row>
+      <entry><type>array</type></entry>
+      <entry>
+       Значение должно быть типа <type>array</type>.
+      </entry>
+      <entry></entry>
+     </row>
+     <row>
+      <entry><type>callable</type></entry>
+      <entry>
+       Значение должно быть корректным <type>callable</type>.
+       Нельзя использовать в качестве объявления для свойств класса.
+      </entry>
+      <entry></entry>
+     </row>
+     <row>
+      <entry><type>bool</type></entry>
+      <entry>
+       Значение должно быть логического типа.
+      </entry>
+      <entry></entry>
+     </row>
+     <row>
+      <entry><type>float</type></entry>
+      <entry>
+       Значение должно быть числом с плавающей запятой.
+      </entry>
+      <entry></entry>
+     </row>
+     <row>
+      <entry><type>int</type></entry>
+      <entry>
+       Значение должно быть целым числом.
+      </entry>
+      <entry></entry>
+     </row>
+     <row>
+      <entry><type>string</type></entry>
+      <entry>
+       Значение должно быть строкой (тип <type>string</type>).
+      </entry>
+      <entry></entry>
+     </row>
+     <row>
+      <entry><type>iterable</type></entry>
+      <entry>
+       Значение может быть либо массивом (тип <type>array</type>) или представлять собой
+       &instanceof; <classname>Traversable</classname>.
+      </entry>
+      <entry>PHP 7.1.0</entry>
+     </row>
+     <row>
+      <entry><type>object</type></entry>
+      <entry>
+       Значение должно быть объектом (тип <type>object</type>).
+      </entry>
+      <entry>PHP 7.2.0</entry>
+     </row>
+     <row>
+      <entry><type>mixed</type></entry>
+      <entry>
+       Значение может иметь любой тип.
+      </entry>
+      <entry>PHP 8.0.0</entry>
+     </row>
+    </tbody>
+   </tgroup>
+  </informaltable>
+
+  <warning>
+   <para>
+    Псевдонимы для указанных выше скалярных типов не поддерживаются.
+    В случае использования они будут считаться за имя класса или интерфейса.
+    К примеру, при использовании в качестве типа <literal>boolean</literal>, он будет
+    ожидать, что значение представляет собой &instanceof; класса или интерфейса
+    <literal>boolean</literal>, а не значение типа <type>bool</type>:
+   </para>
+   <para>
+    <example>
+     <programlisting role="php">
+<![CDATA[
+<?php
+    function test(boolean $param) {}
+    test(true);
+?>
+]]>
+     </programlisting>
+     &example.outputs.8;
+     <screen>
+<![CDATA[
+Warning: "boolean" will be interpreted as a class name. Did you mean "bool"? Write "\boolean" to suppress this warning in /in/9YrUX on line 2
+
+Fatal error: Uncaught TypeError: test(): Argument #1 ($param) must be of type boolean, bool given, called in - on line 3 and defined in -:2
+Stack trace:
+#0 -(3): test(true)
+#1 {main}
+  thrown in - on line 2
+]]>
+     </screen>
+    </example>
+   </para>
+  </warning>
+
+  <sect3 xml:id="language.types.declarations.examples">
+   &reftitle.examples;
+   <example>
+    <title>Объявление типа для класса</title>
+    <programlisting role="php">
+<![CDATA[
+<?php
+class C {}
+class D extends C {}
+
+// Не является наследником C.
+class E {}
+
+function f(C $c) {
+    echo get_class($c)."\n";
+}
+
+f(new C);
+f(new D);
+f(new E);
+?>
+]]>
+    </programlisting>
+    &example.outputs.8;
+    <screen>
+<![CDATA[
+C
+D
+
+Fatal error: Uncaught TypeError: f(): Argument #1 ($c) must be of type C, E given, called in /in/gLonb on line 14 and defined in /in/gLonb:8
+Stack trace:
+#0 -(14): f(Object(E))
+#1 {main}
+  thrown in - on line 8
+]]>
+    </screen>
+   </example>
+
+   <example>
+    <title>Объявление типа для интерфейса</title>
+    <programlisting role="php">
+<![CDATA[
+<?php
+interface I { public function f(); }
+class C implements I { public function f() {} }
+
+// Не реализует интерфейс I.
+class E {}
+
+function f(I $i) {
+    echo get_class($i)."\n";
+}
+
+f(new C);
+f(new E);
+?>
+]]>
+    </programlisting>
+    &example.outputs.8;
+    <screen>
+<![CDATA[
+C
+
+Fatal error: Uncaught TypeError: f(): Argument #1 ($i) must be of type I, E given, called in - on line 13 and defined in -:8
+Stack trace:
+#0 -(13): f(Object(E))
+#1 {main}
+  thrown in - on line 8
+]]>
+    </screen>
+   </example>
+
+   <example>
+    <title>Объявление типа возвращаемого значения</title>
+    <programlisting role="php">
+<![CDATA[
+<?php
+function sum($a, $b): float {
+    return $a + $b;
+}
+
+// Обратите внимание, что будет возвращено число с плавающей запятой.
+var_dump(sum(1, 2));
+?>
+]]>
+    </programlisting>
+    &example.outputs;
+    <screen>
+<![CDATA[
+float(3)
+]]>
+    </screen>
+   </example>
+
+   <example>
+    <title>Возвращение объекта</title>
+    <programlisting role="php">
+<![CDATA[
+<?php
+class C {}
+
+function getC(): C {
+    return new C;
+}
+
+var_dump(getC());
+?>
+]]>
+    </programlisting>
+    &example.outputs;
+    <screen>
+<![CDATA[
+object(C)#1 (0) {
+}
+]]>
+    </screen>
+   </example>
+  </sect3>
+ </sect2>
+
+ <sect2 xml:id="language.types.declarations.nullable">
+  <title>Обнуляемые типы</title>
+
+  <para>
+   Начиная с PHP 7.1.0, объявления типов могут быть помечены как обнуляемые, путём
+   добавления префикса в виде знака вопроса(<literal>?</literal>).
+   Это означает, что значение может быть как объявленного типа, так и быть равным &null;.
+  </para>
+
+  <para>
+   <example>
+    <title>Объявление обнуляемых типов</title>
+    <programlisting role="php">
+<![CDATA[
+<?php
+class C {}
+
+function f(?C $c) {
+    var_dump($c);
+}
+
+f(new C);
+f(null);
+?>
+]]>
+    </programlisting>
+    &example.outputs;
+    <screen>
+<![CDATA[
+object(C)#1 (0) {
+}
+NULL
+]]>
+    </screen>
+   </example>
+
+   <example>
+    <title>Обнуляемые типы для возвращаемого значения</title>
+    <programlisting role="php">
+<![CDATA[
+<?php
+function get_item(): ?string {
+    if (isset($_GET['item'])) {
+        return $_GET['item'];
+    } else {
+        return null;
+    }
+}
+?>
+]]>
+    </programlisting>
+   </example>
+  </para>
+
+  <note>
+   <para>
+    До PHP 7.1.0, было возможно задавать обнуляемые типы аргументов функций путём
+    задания значения по умолчанию равного <literal>null</literal>.
+    Так делать не рекомендуется, поскольку это может поломать наследование.
+   </para>
+   <example>
+    <title>Старый способ задавать обнуляемые типы для аргументов</title>
+    <programlisting role="php">
+<![CDATA[
+<?php
+class C {}
+
+function f(C $c = null) {
+    var_dump($c);
+}
+
+f(new C);
+f(null);
+?>
+]]>
+    </programlisting>
+    &example.outputs;
+    <screen>
+<![CDATA[
+object(C)#1 (0) {
+}
+NULL
+]]>
+    </screen>
+   </example>
+  </note>
+ </sect2>
+
+ <sect2 xml:id="language.types.declarations.union">
+  <title>Объединённые типы</title>
+  <para>
+   Объединённые типы позволяют использовать несколько типов, а не исключительно один.
+   Для их объявления используется следующий синтаксис <literal>T1|T2|...</literal>.
+   Объединённые типы доступны начиная с PHP 8.0.0.
+  </para>
+
+  <sect3 xml:id="language.types.declarations.union.nullable">
+   <title>Обнуляемые объединённые типы</title>
+   <para>
+    Тип <literal>null</literal> можно использовать как часть объединений следующим образов:
+    <literal>T1|T2|null</literal>.
+    Существующая нотация <literal>?T</literal> рассматривается как сокращение для <literal>T|null</literal>.
+   </para>
+
+   <caution>
+    <simpara>
+     <literal>null</literal> не может использоваться как отдельный тип.
+    </simpara>
+   </caution>
+  </sect3>
+
+  <sect3 xml:id="language.types.declarations.union.false">
+   <title>Псевдо-тип false</title>
+   <para>
+    Псевдо-тип <literal>false</literal> поддерживается как часть объединённых типов.
+    Он добавлен по историческим причинам, так как многие встроеные функции возвращают
+    <literal>false</literal> вместо <literal>null</literal> в случае ошибок.
+    Классический пример - функция <function>strpos</function>.
+   </para>
+
+   <caution>
+    <simpara>
+     <literal>false</literal> нельзя использовать как самостоятельный тип (включая
+     обнуляемый вариант).
+     Таким образом, все объявления такого типа недопустимы: <literal>false</literal>, <literal>false|null</literal>
+     и <literal>?false</literal>.
+    </simpara>
+   </caution>
+   <caution>
+    <simpara>
+     Обратите внимание, что псевдо-тип <literal>true</literal> <emphasis>не</emphasis> существует.
+    </simpara>
+   </caution>
+  </sect3>
+
+  <sect3 xml:id="language.types.declarations.union.redundant">
+   <title>Дублирующиеся и повторяющиеся типы</title>
+   <para>
+    Для отлова простых ошибок в объединённых объявлениях, повторяющиеся типы, которые
+    можно отследить без загрузки класса, приведут к ошибке компиляции.
+    В том числе:
+    <itemizedlist>
+     <listitem>
+      <simpara>
+       Каждый тип распознаваемый по имени должен встречаться только один раз.
+       Типы вида <literal>int|string|INT</literal> приведут к ошибке.
+      </simpara>
+     </listitem>
+     <listitem>
+      <simpara>
+       Если используется <type>bool</type>, то использовать дополнительно <type>false</type> нельзя.
+      </simpara>
+     </listitem>
+     <listitem>
+      <simpara>
+       Если используется тип <type>object</type>, то дополнительное использование имён классов недопустимо.
+      </simpara>
+     </listitem>
+     <listitem>
+      <simpara>
+       Если используется <type>iterable</type>, то к нему нельзя добавить <type>array</type>
+       или <classname>Traversable</classname>.
+      </simpara>
+     </listitem>
+    </itemizedlist>
+   </para>
+
+   <note>
+    <simpara>
+     Это не гарантирует, что все объединённые типы объявлены корректно, поскольку
+     такая проверка потребует загрузки всех используемых классов.
+    </simpara>
+   </note>
+
+   <para>
+    К примеру, если <literal>A</literal> и <literal>B</literal> являются псевдонимами одного и того же класса,
+    то <literal>A|B</literal> выглядит как корректный объединённый тип, даже если фактически объявление
+    может быть сокращено до <literal>A</literal> или <literal>B</literal>.
+    Аналогично, если <code>B extends A {}</code>, то <literal>A|B</literal> тоже
+    выглядит корректным типом, не смотря на то, что он может быть сокращён до
+    <literal>A</literal>.
+
+    <informalexample>
+     <programlisting role="php">
+<![CDATA[
+<?php
+function foo(): int|INT {} // Запрещено
+function foo(): bool|false {} // Запрещено
+
+use A as B;
+function foo(): A|B {} // Запрещено ("use" является частью разрешения имён)
+
+class_alias('X', 'Y');
+function foo(): X|Y {} // Допустимо (повторение будет определено только во время выполнения)
+?>
+]]>
+     </programlisting>
+    </informalexample>
+   </para>
+  </sect3>
+
+ </sect2>
+
+ <sect2 xml:id="language.types.declarations.return-only">
+  <title>Типы, подходящие только для возвращаемого значения</title>
+
+  <sect3 xml:id="language.types.declarations.void">
+   <title>void</title>
+   <para>
+    Тип <literal>void</literal> означает, что функция ничего не возвращает.
+    Соответственно он не может быть частью объединения.
+    Доступно с PHP 7.1.0.
+   </para>
+  </sect3>
+
+  <sect3 xml:id="language.types.declarations.static">
+   <title>static</title>
+   <para>
+    Значение должно представлять собой &instanceof; того же класса, в котором был вызван метод.
+    Доступно с PHP 8.0.0.
+   </para>
+  </sect3>
+ </sect2>
+
+ <sect2 xml:id="language.types.declarations.strict">
+  <title>Строгое типизирование</title>
+
+  <para>
+   По умолчанию, PHP будет преобразовывать значения неправильного типа в ожидаемые.
+   К примеру, если в функцию передать параметр типа <type>int</type> в аргумент,
+   объявленный как <type>string</type>, то он преобразуется в <type>string</type>.
+  </para>
+
+  <para>
+   Можно включить режим строгого типизирования на уровне файла. В этом
+   режиме, тип значения должен строго соответствовать объявленому, иначе будет выброшено
+   исключение <classname>TypeError</classname>.
+   Единственным исключением из этого правила является передача значения типа <type>int</type>
+   туда, где ожидается <type>float</type>.
+  </para>
+
+  <warning>
+   <simpara>
+    На вызовы из внутренних функций, действие <literal>strict_types</literal> не распространяется.
+   </simpara>
+  </warning>
+
+  <para>
+   Для включения строгой типизации используется оператор &declare; с объявлением
+   <literal>strict_types</literal>:
+  </para>
+
+  <note>
+   <para>
+    Строгая типизация применяется к вызовам функций, сделанным
+    <emphasis>изнутри</emphasis> файла с включенной строгой типизацией,
+    а не к функциям, объявленным в этом файле. Если из файла без включенной строгой
+    типизации вызывается функция, которая была определена в файле со строгой типизацией,
+    то будет использованы его предпочтения по типизации - т.е. правила строгой типизации
+    будут проигнорированы и для значений будет применяться приведение типов.
+   </para>
+  </note>
+
+  <note>
+   <para>
+    Строгая типизация определяется только для объявлений скалярных типов.
+   </para>
+  </note>
+
+  <example>
+   <title>Строгая типизация для значений аргументов</title>
+   <programlisting role="php">
+<![CDATA[
+<?php
+declare(strict_types=1);
+
+function sum(int $a, int $b) {
+    return $a + $b;
+}
+
+var_dump(sum(1, 2));
+var_dump(sum(1.5, 2.5));
+?>
+]]>
+   </programlisting>
+   &example.outputs.8;
+   <screen>
+<![CDATA[
+int(3)
+
+Fatal error: Uncaught TypeError: sum(): Argument #1 ($a) must be of type int, float given, called in - on line 9 and defined in -:4
+Stack trace:
+#0 -(9): sum(1.5, 2.5)
+#1 {main}
+  thrown in - on line 4
+]]>
+   </screen>
+  </example>
+
+  <example>
+   <title>Приведение типов для значений аргументов</title>
+   <programlisting role="php">
+<![CDATA[
+<?php
+function sum(int $a, int $b) {
+    return $a + $b;
+}
+
+var_dump(sum(1, 2));
+
+// Переданные значения будут приведены к целым числам: обратите внимание на вывод ниже!
+var_dump(sum(1.5, 2.5));
+?>
+]]>
+   </programlisting>
+   &example.outputs;
+   <screen>
+<![CDATA[
+int(3)
+int(3)
+]]>
+   </screen>
+  </example>
+
+  <example>
+   <title>Строгая типизация для возвращаемых значений</title>
+   <programlisting role="php">
+<![CDATA[
+<?php
+declare(strict_types=1);
+
+function sum($a, $b): int {
+    return $a + $b;
+}
+
+var_dump(sum(1, 2));
+var_dump(sum(1, 2.5));
+?>
+]]>
+   </programlisting>
+   &example.outputs;
+   <screen>
+<![CDATA[
+int(3)
+
+Fatal error: Uncaught TypeError: sum(): Return value must be of type int, float returned in -:5
+Stack trace:
+#0 -(9): sum(1, 2.5)
+#1 {main}
+  thrown in - on line 5
+]]>
+   </screen>
+  </example>
+ </sect2>
+
+ <sect2 xml:id="language.types.declarations.union.coercive">
+  <title>Приведение для объеденённых типов</title>
+  <para>
+   Если <literal>strict_types</literal> не разрешено, то объявления скалярных типов
+   подлежат ограниченному неявному приведению. Если фактический тип не является частью объединения,
+   то используется следующий порядок приведения типов:
+
+   <orderedlist>
+    <listitem>
+     <simpara>
+      <type>int</type>
+     </simpara>
+    </listitem>
+    <listitem>
+     <simpara>
+      <type>float</type>
+     </simpara>
+    </listitem>
+    <listitem>
+     <simpara>
+      <type>string</type>
+     </simpara>
+    </listitem>
+    <listitem>
+     <simpara>
+      <type>bool</type>
+     </simpara>
+    </listitem>
+   </orderedlist>
+
+   Если тип присутствует в объединении и значение может быть приведено к нему основываясь на
+   существующей семантике приведения типов PHP, то поизойдёт приведение к нему. Если нет, то
+   проверится следующий тип в списке.
+  </para>
+
+  <caution>
+   <para>
+    Единственным исключением является приведение строки в случае, если в объединении
+    одновременно присутствуют и <type>int</type> и <type>float</type>. В таком случае будет
+    выбрано наиболее подходящий тип по правилу приведения "числовых строк".
+    К примеру, для <literal>"42"</literal> бдет выбран тип <type>int</type>,
+    а для <literal>"42.0"</literal> тип <type>float</type>.
+   </para>
+  </caution>
+
+  <note>
+   <para>
+    Типы, не входящие в данный список не подходят для целей неявного приведения.
+    targets for implicit coercion. В часности, для <literal>null</literal>
+    и <literal>false</literal> неявного приведения не случится.
+   </para>
+  </note>
+
+  <example>
+   <title>Пример приведения для объединённых типов</title>
+   <programlisting role="php">
+<![CDATA[
+<?php
+// int|string
+42    --> 42          // явный тип
+"42"  --> "42"        // явный тип
+new ObjectWithToString --> строка с результатом выполнения __toString()
+                      // Объекты никогда не будут приведены к целому числу, даже если вернут "числовую строку"
+42.0  --> 42          // float совместим с int
+42.1  --> 42          // float совместим с int
+1e100 --> "1.0E+100"  // float слишком большой для типа int, преобразуется в строку
+INF   --> "INF"       // float слишком большой для типа int, преобразуется в строку
+true  --> 1           // bool совместим с int
+[]    --> TypeError   // array не совместим ни с int ни со string
+
+// int|float|bool
+"45"    --> 45        // целочисленная "чистовая строка"
+"45.0"  --> 45.0      // "чистовая строка" с плавающей запятой
+
+"45X"   --> true      // не "чистовая строка", приведётся к bool
+""      --> false     // не "чистовая строка", приведётся к bool
+"X"     --> true      // не "чистовая строка", приведётся к bool
+[]      --> TypeError // array не совместим ни с int ни с float ни с bool
+?>
+]]>
+   </programlisting>
+  </example>
+ </sect2>
+
+ <!-- TODO figure out what do to with these things -->
+ <sect2 xml:id="language.types.declarations.misc">
+  <title>Дополнительно</title>
+  <example>
+   <title>Типизированые параметры передаваемые по ссылке</title>
+   <simpara>
+    Объявление типов для параметров передаваемых по ссылке проверяется только на этапе вызова функции.
+    Не никакой гарантии, что после выхода из функции тип переменной останется неизменным.
+   </simpara>
+   <programlisting role="php">
+<![CDATA[
+<?php
+function array_baz(array &$param)
+{
+    $param = 1;
+}
+$var = [];
+array_baz($var);
+var_dump($var);
+array_baz($var);
+?>
+]]>
+   </programlisting>
+   &example.outputs.8;
+   <screen>
+<![CDATA[
+int(1)
+
+Fatal error: Uncaught TypeError: array_baz(): Argument #1 ($param) must be of type array, int given, called in - on line 9 and defined in -:2
+Stack trace:
+#0 -(9): array_baz(1)
+#1 {main}
+  thrown in - on line 2
+]]>
+   </screen>
+  </example>
+
+  <example>
+   <title>Обработка <classname>TypeError</classname></title>
+   <programlisting role="php">
+<![CDATA[
+<?php
+declare(strict_types=1);
+
+function sum(int $a, int $b) {
+    return $a + $b;
+}
+
+try {
+    var_dump(sum(1, 2));
+    var_dump(sum(1.5, 2.5));
+} catch (TypeError $e) {
+    echo 'Ошибка: ', $e->getMessage();
+}
+?>
+]]>
+   </programlisting>
+   &example.outputs.8;
+   <screen>
+<![CDATA[
+int(3)
+Ошибка: sum(): Argument #1 ($a) must be of type int, float given, called in - on line 10
+]]>
+   </screen>
+  </example>
+ </sect2>
+
+</sect1>
+
+<!-- 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
+-->


Property changes on: phpdoc/ru/trunk/language/types/declarations.xml
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
\ No newline at end of property