<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/language.types.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ru',
  ),
  'this' => 
  array (
    0 => 'language.types.declarations.php',
    1 => 'Объявления типов',
    2 => 'Объявления типов',
  ),
  'up' => 
  array (
    0 => 'language.types.php',
    1 => 'Типы',
  ),
  'prev' => 
  array (
    0 => 'language.types.iterable.php',
    1 => 'Итерируемые значения',
  ),
  'next' => 
  array (
    0 => 'language.types.type-juggling.php',
    1 => 'Жонглирование типами',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ru',
    'path' => 'language/types/declarations.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.types.declarations" class="sect1">
 <h2 class="title">Объявления типов</h2>

 <p class="para">
  Объявления типов добавляют параметрам функций, значениям возврата,
  начиная с PHP 7.4.0 свойствам класса и начиная с PHP 8.3.0 константам класса.
  Объявления типов гарантируют, что при вызове значение принадлежит заданному типу,
  иначе PHP выбросит ошибку <span class="classname"><a href="class.typeerror.php" class="classname">TypeError</a></span>.
 </p>

 <p class="para">
  Каждый тип, который поддерживает PHP, за исключением ресурсов (<span class="type"><a href="language.types.resource.php" class="type resource">resource</a></span>),
  разрешается указывать в пользовательском объявлении типа.
  Страница содержит журнал изменений доступности отдельных типов
  и документацию, которая описывает правила объявления типов.
 </p>

 <blockquote class="note"><p><strong class="note">Замечание</strong>: 
  <p class="para">
   Класс, который реализует метод интерфейса или переопределяет метод
   родительского класса,
   подчиняется правилам совместимости.
   Метод совместим, если следует
   <a href="language.oop5.variance.php" class="link">правилам вариантности</a>.
  </p>
 </p></blockquote>

 <div class="sect2">
  <h3 class="title">Список изменений</h3>
  <table class="doctable informaltable">
   
    <thead>
     <tr>
      <th>Версия</th>
      <th>Описание</th>
     </tr>

    </thead>

    <tbody class="tbody">
     <tr>
      <td>8.3.0</td>
      <td>
       Добавили поддержку типизации констант классов, интерфейсов, трейтов и перечислений.
      </td>
     </tr>

     <tr>
      <td>8.2.0</td>
      <td>
       Добавили поддержку <abbr title="Disjunctive Normal Form">DNF</abbr>-типов.
      </td>
     </tr>

     <tr>
      <td>8.2.0</td>
      <td>
       Добавили поддержку самостоятельного типа <span class="type"><a href="language.types.singleton.php" class="type true">true</a></span>.
      </td>
     </tr>

     <tr>
      <td>8.2.0</td>
      <td>
       Типы <span class="type"><a href="language.types.null.php" class="type null">null</a></span> и <span class="type"><a href="language.types.singleton.php" class="type false">false</a></span> разрешили указывать отдельно.
      </td>
     </tr>

     <tr>
      <td>8.1.0</td>
      <td>
       Добавили поддержку пересечений типов.
      </td>
     </tr>

     <tr>
      <td>8.1.0</td>
      <td>
       Возврат по ссылке из функции с типом значения возврата <span class="type"><span class="type"><a href="language.types.void.php" class="type void">void</a></span></span> устарел.
      </td>
     </tr>

     <tr>
      <td>8.1.0</td>
      <td>
       Для значения возврата добавили поддержку типа <span class="type"><a href="language.types.never.php" class="type never">never</a></span>.
      </td>
     </tr>

     <tr>
      <td>8.0.0</td>
      <td>
       Для значения возврата добавили поддержку типа <span class="type"><a href="language.types.mixed.php" class="type mixed">mixed</a></span>.
      </td>
     </tr>

     <tr>
      <td>8.0.0</td>
      <td>
       Для значения возврата добавили поддержку типа <span class="type">static</span>.
      </td>
     </tr>

     <tr>
      <td>8.0.0</td>
      <td>
       Добавили поддержку объединения типов.
      </td>
     </tr>

     <tr>
      <td>7.4.0</td>
      <td>
       Добавили поддержку типизации свойств классов.
      </td>
     </tr>

     <tr>
      <td>7.2.0</td>
      <td>
       Для значения возврата добавили поддержку типа <span class="type"><a href="language.types.object.php" class="type object">object</a></span>.
      </td>
     </tr>

     <tr>
      <td>7.1.0</td>
      <td>
       Для значения возврата добавили поддержку типа <span class="type"><a href="language.types.iterable.php" class="type iterable">iterable</a></span>.
      </td>
     </tr>

     <tr>
      <td>7.1.0</td>
      <td>
       Для значения возврата добавили поддержку типа <span class="type"><span class="type"><a href="language.types.void.php" class="type void">void</a></span></span>.
      </td>
     </tr>

     <tr>
      <td>7.1.0</td>
      <td>
       Для значения возврата добавили поддержку обнуляемого типа.
      </td>
     </tr>

    </tbody>
   
  </table>

 </div>

 <div class="sect2" id="language.types.declarations.base">
  <h3 class="title">Атомарные типы</h3>

  <p class="simpara">
   Атомарные типы ведут себя прямолинейно, но с рядом оговорок,
   которые описывает этот раздел.
  </p>

  <div class="sect3" id="language.types.declarations.base.scalar">
   <h4 class="title">Скалярные типы</h4>
   <div class="warning"><strong class="warning">Внимание</strong>
    <p class="para">
     Псевдонимы имён для скалярных типов, к которым относятся типы <span class="type"><a href="language.types.boolean.php" class="type bool">bool</a></span>, <span class="type"><a href="language.types.integer.php" class="type int">int</a></span>,
     <span class="type"><a href="language.types.float.php" class="type float">float</a></span> и <span class="type"><a href="language.types.string.php" class="type string">string</a></span>, не поддерживаются.
     Вместо назначения псевдонимов названия классов и интерфейсов трактуются как типы.
     Например, буквальное название <code class="literal">boolean</code> в объявлении типа потребует,
     чтобы значение выполняло условие <a href="language.operators.type.php" class="link"><code class="literal">instanceof</code></a> в отношении класса или интерфейса
     <code class="literal">boolean</code>, а не принадлежало типу <span class="type"><a href="language.types.boolean.php" class="type bool">bool</a></span>:
    </p>
    <div class="informalexample">
     <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">function </span><span style="color: #0000BB">test</span><span style="color: #007700">(</span><span style="color: #0000BB">boolean $param</span><span style="color: #007700">) {}<br /></span><span style="color: #0000BB">test</span><span style="color: #007700">(</span><span style="color: #0000BB">true</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

     
<p class="para">
 Результат выполнения приведённого примера в PHP 8:
</p>

     <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
Warning: &quot;boolean&quot; will be interpreted as a class name. Did you mean &quot;bool&quot;? Write &quot;\boolean&quot; 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
</pre></div>
     </div>
    </div>
   </div>
  </div>

  <div class="sect3" id="language.types.declarations.void">
   <h4 class="title">Тип void</h4>
   <blockquote class="note"><p><strong class="note">Замечание</strong>: 
    <p class="para">
     Возврат по ссылке из <span class="type"><span class="type"><a href="language.types.void.php" class="type void">void</a></span></span>-функции устарел начиная с PHP 8.1.0,
     поскольку такая функция противоречива.
     Раньше при вызове такой функции уже выдавалась ошибка уровня <strong><code><a href="errorfunc.constants.php#constant.e-notice">E_NOTICE</a></code></strong>:
     <span class="computeroutput">Только ссылки на переменные должны возвращаться по ссылке</span>.

     <div class="informalexample">
      <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">function &amp;</span><span style="color: #0000BB">test</span><span style="color: #007700">(): </span><span style="color: #0000BB">void </span><span style="color: #007700">{}<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
      </div>

     </div>
    </p>
   </p></blockquote>
  </div>

  <div class="sect3" id="language.types.declarations.base.function">
   <h4 class="title">Тип Callable</h4>
   <p class="para">
    Свойствам класса нельзя объявлять тип callable.
   </p>

   <blockquote class="note"><p><strong class="note">Замечание</strong>: 
    <span class="simpara">
     Тип callable нельзя указывать как название функции.
    </span>
   </p></blockquote>
  </div>

  <div class="sect3" id="language.types.declarations.references">
   <h4 class="title">Объявление типов параметрам, которые принимают ссылку</h4>

   <p class="simpara">
    Параметр, который принимает ссылку, проверяет
    тип переменной <em>только</em> при входе в функцию, в начале вызова,
    но не при возврате из функции,
    поэтому в функции возможно изменение типа ссылки на переменную.
   </p>
   <div class="example" id="example-1">
    <p><strong>Пример #1 Типизированный параметр, который принимает ссылку</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">function </span><span style="color: #0000BB">array_baz</span><span style="color: #007700">(array &amp;</span><span style="color: #0000BB">$param</span><span style="color: #007700">)<br />{<br />    </span><span style="color: #0000BB">$param </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">$var </span><span style="color: #007700">= [];<br /></span><span style="color: #0000BB">array_baz</span><span style="color: #007700">(</span><span style="color: #0000BB">$var</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$var</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">array_baz</span><span style="color: #007700">(</span><span style="color: #0000BB">$var</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

    
<div class="example-contents"><p>
 Вывод приведённого примера будет похож на:
</p></div>

    <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
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
</pre></div>
    </div>
   </div>
  </div>
 </div>

 <div class="sect2" id="language.types.declarations.composite">
  <h3 class="title">Примечание по составным типам</h3>
  <p class="para">
   На объявления составных типов распространяется ряд ограничений;
   компилятор выполняет проверку избыточности типов,
   чтобы предотвратить простые ошибки.
  </p>

  <div class="caution"><strong class="caution">Предостережение</strong>
   <p class="simpara">
    Комбинирование пересечений и объединений типов оставалось невозможным
    до PHP 8.2.0 и введения DNF-типов.
   </p>
  </div>

  <div class="sect3" id="language.types.declarations.composite.union">
   <h4 class="title">Объединение типов</h4>
   <div class="warning"><strong class="warning">Внимание</strong>
    <p class="simpara">
     Невозможно определить в объединённом типе два одноэлементных типа <span class="type"><a href="language.types.singleton.php" class="type false">false</a></span> и <span class="type"><a href="language.types.singleton.php" class="type true">true</a></span>.
     Вместо этого указывают тип <span class="type"><a href="language.types.boolean.php" class="type bool">bool</a></span>.
    </p>
   </div>

   <div class="caution"><strong class="caution">Предостережение</strong>
    <p class="simpara">
     До PHP 8.2.0 запрещали определять типы <span class="type"><a href="language.types.singleton.php" class="type false">false</a></span> и <span class="type"><a href="language.types.null.php" class="type null">null</a></span> отдельно,
     поэтому объединение типов, которое состояло только из этих типов, оставалось недопустимым.
     К таким объединениям относятся типы: <span class="type"><a href="language.types.singleton.php" class="type false">false</a></span>, <code class="literal">false|null</code>
     и <code class="literal">?false</code>.
    </p>
   </div>

   <div class="sect4" id="language.types.declarations.nullable">
    <h5 class="title">Синтаксический сахар обнуляемого типа</h5>

    <p class="para">
     Объявление отдельного базового типа помечают как nullable путём
     добавления к типу префикса в виде
     вопросительного знака (<code class="literal">?</code>).
     Поэтому типы <code class="literal">?T</code> и <code class="literal">T|null</code> идентичны.
    </p>

    <blockquote class="note"><p><strong class="note">Замечание</strong>: 
     <span class="simpara">
      Этот синтаксис поддерживается с PHP 7.1.0
      и предшествует поддержке объединения типов.
     </span>
    </p></blockquote>

    <blockquote class="note"><p><strong class="note">Замечание</strong>: 
     <p class="para">
      Ещё один способ объявить nullable-параметр —
      указать значением по умолчанию значение <code class="literal">null</code>.
      Объявлять тип таким способом не рекомендуют, поскольку изменение значения по умолчанию
      в дочернем классе нарушит совместимость типов,
      и к объявлению типа потребуется добавить тип <span class="type"><a href="language.types.null.php" class="type null">null</a></span>.
      Это поведение также устарело начиная с PHP 8.4.
     </p>
     <div class="example" id="example-2">
      <p><strong>Пример #2 Старый способ указать nullable-параметр</strong></p>
      <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">C </span><span style="color: #007700">{}<br /><br />function </span><span style="color: #0000BB">f</span><span style="color: #007700">(</span><span style="color: #0000BB">C $c </span><span style="color: #007700">= </span><span style="color: #0000BB">null</span><span style="color: #007700">)<br />{<br />    </span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$c</span><span style="color: #007700">);<br />}<br /><br /></span><span style="color: #0000BB">f</span><span style="color: #007700">(new </span><span style="color: #0000BB">C</span><span style="color: #007700">());<br /></span><span style="color: #0000BB">f</span><span style="color: #007700">(</span><span style="color: #0000BB">null</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
      </div>

      
<div class="example-contents"><p>
 Результат выполнения приведённого примера:
</p></div>

      <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
object(C)#1 (0) {
}
NULL
</pre></div>
      </div>
     </div>
    </p></blockquote>
   </div>
  </div>

  <div class="sect3" id="language.types.declarations.composite.redundant">
   <h4 class="title">Повторные и избыточные типы</h4>
   <p class="para">
    Правила объявления составных типов предусматривают ряд ограничений.
    При компиляции кода с избыточными типами, которые возможно обнаружить без загрузки классов,
    возникнет ошибка. Примеры ошибок в объявлениях составных типов включают:

    <ul class="itemizedlist">
     <li class="listitem">
      <span class="simpara">
       Повторение типа в объявлениях наподобие <code class="literal">int|string|INT</code>
       или <code class="literal">Countable&amp;Traversable&amp;COUNTABLE</code> вызовет ошибку,
       поскольку после разрешения названия типа внутренними средствами языка тип встретится больше одного раза.
      </span>
     </li>
     <li class="listitem">
      <span class="simpara">
       Объявление типа <span class="type"><a href="language.types.mixed.php" class="type mixed">mixed</a></span> или <span class="type"><a href="language.types.never.php" class="type never">never</a></span> с другими типами вызовет ошибку.
      </span>
     </li>
     <li class="listitem">
      <span class="simpara">Ошибки объединения типов:</span>
      <ul class="itemizedlist">
       <li class="listitem">
        <span class="simpara">
         Избыточное объявление типа <span class="type"><a href="language.types.singleton.php" class="type false">false</a></span> или <span class="type"><a href="language.types.singleton.php" class="type true">true</a></span>
         вместе с типом <span class="type"><a href="language.types.boolean.php" class="type bool">bool</a></span>.
        </span>
       </li>
       <li class="listitem">
        <span class="simpara">
         Избыточное объявление типа класса вместе с типом <span class="type"><a href="language.types.object.php" class="type object">object</a></span>.
        </span>
       </li>
       <li class="listitem">
        <span class="simpara">
         Избыточное объявление типа <span class="type"><a href="language.types.array.php" class="type array">array</a></span> или <span class="classname"><a href="class.traversable.php" class="classname">Traversable</a></span>
         вместе с типом <span class="type"><a href="language.types.iterable.php" class="type iterable">iterable</a></span>.
        </span>
       </li>
      </ul>
     </li>
     <li class="listitem">
      <span class="simpara">Ошибки пересечения типов:</span>
      <ul class="itemizedlist">
       <li class="listitem">
        <span class="simpara">
         Объявление типа, который не относится к классовому типу.
        </span>
       </li>
       <li class="listitem">
        <span class="simpara">
         Объявление типа <span class="type">self</span>, <span class="type">parent</span>
         или <span class="type">static</span>.
        </span>
       </li>
      </ul>
     </li>
     <li class="listitem">
      <span class="simpara">Ошибки объявления <abbr title="Disjunctive Normal Form">DNF</abbr>-типов:</span>
      <ul class="itemizedlist">
       <li class="listitem">
        <span class="simpara">
         Избыточное объявление более строго типа с более общим типом.
        </span>
       </li>
       <li class="listitem">
        <span class="simpara">
         Объявление дубликатов в пересечении типов.
        </span>
       </li>
      </ul>
     </li>
    </ul>
   </p>

   <blockquote class="note"><p><strong class="note">Замечание</strong>: 
    <span class="simpara">
     Эти проверки не гарантируют, что тип «минимален» и не содержит повторений или избыточных типов,
     поскольку для этого потребовалось бы загрузить все указанные типы классов.
    </span>
   </p></blockquote>

   <p class="para">
    Например, если типы <code class="literal">A</code> и <code class="literal">B</code> — псевдонимы классов,
    то составной тип <code class="literal">A|B</code> остаётся корректным объединением типов,
    даже если тип получится свести либо к <code class="literal">A</code>, либо к <code class="literal">B</code>.
    Аналогично, если класс <code class="code">B extends A {}</code>, то составной тип <code class="literal">A|B</code> также относится
    к корректному объединению типов, даже если тип получится свести только к типу <code class="literal">A</code>.

    <div class="informalexample">
     <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">function </span><span style="color: #0000BB">foo</span><span style="color: #007700">(): </span><span style="color: #0000BB">int</span><span style="color: #007700">|</span><span style="color: #0000BB">INT </span><span style="color: #007700">{} </span><span style="color: #FF8000">// Запрещено<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">foo</span><span style="color: #007700">(): </span><span style="color: #0000BB">bool</span><span style="color: #007700">|</span><span style="color: #0000BB">false </span><span style="color: #007700">{} </span><span style="color: #FF8000">// Запрещено<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">foo</span><span style="color: #007700">(): </span><span style="color: #0000BB">int</span><span style="color: #007700">&amp;</span><span style="color: #0000BB">Traversable </span><span style="color: #007700">{} </span><span style="color: #FF8000">// Запрещено<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">foo</span><span style="color: #007700">(): </span><span style="color: #0000BB">self</span><span style="color: #007700">&amp;</span><span style="color: #0000BB">Traversable </span><span style="color: #007700">{} </span><span style="color: #FF8000">// Запрещено<br /><br /></span><span style="color: #007700">use </span><span style="color: #0000BB">A </span><span style="color: #007700">as </span><span style="color: #0000BB">B</span><span style="color: #007700">;<br />function </span><span style="color: #0000BB">foo</span><span style="color: #007700">(): </span><span style="color: #0000BB">A</span><span style="color: #007700">|</span><span style="color: #0000BB">B </span><span style="color: #007700">{} </span><span style="color: #FF8000">// Запрещено (оператор "use" только создаёт псевдоним через механизм разрешения имён, а не отдельный тип)<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">foo</span><span style="color: #007700">(): </span><span style="color: #0000BB">A</span><span style="color: #007700">&amp;</span><span style="color: #0000BB">B </span><span style="color: #007700">{} </span><span style="color: #FF8000">// Запрещено (оператор "use" только создаёт псевдоним через механизм разрешения имён, а не отдельный тип)<br /><br /></span><span style="color: #0000BB">class_alias</span><span style="color: #007700">(</span><span style="color: #DD0000">'X'</span><span style="color: #007700">, </span><span style="color: #DD0000">'Y'</span><span style="color: #007700">);<br />function </span><span style="color: #0000BB">foo</span><span style="color: #007700">(): </span><span style="color: #0000BB">X</span><span style="color: #007700">|</span><span style="color: #0000BB">Y </span><span style="color: #007700">{} </span><span style="color: #FF8000">// Разрешено (избыточность обнаружится только при выполнении кода)<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">foo</span><span style="color: #007700">(): </span><span style="color: #0000BB">X</span><span style="color: #007700">&amp;</span><span style="color: #0000BB">Y </span><span style="color: #007700">{} </span><span style="color: #FF8000">// Разрешено (избыточность обнаружится только при выполнении кода)<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </p>
  </div>
 </div>

 <div class="sect2" id="language.types.declarations.examples">
  <h3 class="title">Примеры</h3>
  <div class="example" id="example-3">
   <p><strong>Пример #3 Пример объявления типа через название класса</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">C </span><span style="color: #007700">{}<br />class </span><span style="color: #0000BB">D </span><span style="color: #007700">extends </span><span style="color: #0000BB">C </span><span style="color: #007700">{}<br /><br /></span><span style="color: #FF8000">// Класс не наследует класс C<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">E </span><span style="color: #007700">{}<br /><br />function </span><span style="color: #0000BB">f</span><span style="color: #007700">(</span><span style="color: #0000BB">C $c</span><span style="color: #007700">)<br />{<br />    echo </span><span style="color: #0000BB">get_class</span><span style="color: #007700">(</span><span style="color: #0000BB">$c</span><span style="color: #007700">).</span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">f</span><span style="color: #007700">(new </span><span style="color: #0000BB">C</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">f</span><span style="color: #007700">(new </span><span style="color: #0000BB">D</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">f</span><span style="color: #007700">(new </span><span style="color: #0000BB">E</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   
<div class="example-contents"><p>
 Результат выполнения приведённого примера в PHP 8:
</p></div>

   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
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
</pre></div>
   </div>
  </div>

  <div class="example" id="example-4">
   <p><strong>Пример #4 Пример объявления типа через название интерфейса</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">interface </span><span style="color: #0000BB">I<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">f</span><span style="color: #007700">();<br />}<br /><br />class </span><span style="color: #0000BB">C </span><span style="color: #007700">implements </span><span style="color: #0000BB">I<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">f</span><span style="color: #007700">() {}<br />}<br /><br /></span><span style="color: #FF8000">// Класс не реализует интерфейс I<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">E </span><span style="color: #007700">{}<br /><br />function </span><span style="color: #0000BB">f</span><span style="color: #007700">(</span><span style="color: #0000BB">I $i</span><span style="color: #007700">)<br />{<br />    echo </span><span style="color: #0000BB">get_class</span><span style="color: #007700">(</span><span style="color: #0000BB">$i</span><span style="color: #007700">) . </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">f</span><span style="color: #007700">(new </span><span style="color: #0000BB">C</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">f</span><span style="color: #007700">(new </span><span style="color: #0000BB">E</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   
<div class="example-contents"><p>
 Результат выполнения приведённого примера в PHP 8:
</p></div>

   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
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
</pre></div>
   </div>
  </div>

  <div class="example" id="example-5">
   <p><strong>Пример #5 Пример объявления типа значения возврата</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">function </span><span style="color: #0000BB">sum</span><span style="color: #007700">(</span><span style="color: #0000BB">$a</span><span style="color: #007700">, </span><span style="color: #0000BB">$b</span><span style="color: #007700">): </span><span style="color: #0000BB">float<br /></span><span style="color: #007700">{<br />    return </span><span style="color: #0000BB">$a </span><span style="color: #007700">+ </span><span style="color: #0000BB">$b</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #FF8000">// Обратите внимание, что функция вернёт значение с типом float<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">sum</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">2</span><span style="color: #007700">));<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   
<div class="example-contents"><p>
 Результат выполнения приведённого примера:
</p></div>

   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
float(3)
</pre></div>
   </div>
  </div>

  <div class="example" id="example-6">
   <p><strong>Пример #6 Возврат объекта</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">C </span><span style="color: #007700">{}<br /><br />function </span><span style="color: #0000BB">getC</span><span style="color: #007700">(): </span><span style="color: #0000BB">C<br /></span><span style="color: #007700">{<br />    return new </span><span style="color: #0000BB">C</span><span style="color: #007700">();<br />}<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">getC</span><span style="color: #007700">());<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   
<div class="example-contents"><p>
 Результат выполнения приведённого примера:
</p></div>

   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
object(C)#1 (0) {
}
</pre></div>
   </div>
  </div>

  <div class="example" id="example-7">
   <p><strong>Пример #7 Объявление параметра с обнуляемым типом</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">C </span><span style="color: #007700">{}<br /><br />function </span><span style="color: #0000BB">f</span><span style="color: #007700">(?</span><span style="color: #0000BB">C $c</span><span style="color: #007700">)<br />{<br />    </span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$c</span><span style="color: #007700">);<br />}<br /><br /></span><span style="color: #0000BB">f</span><span style="color: #007700">(new </span><span style="color: #0000BB">C</span><span style="color: #007700">());<br /></span><span style="color: #0000BB">f</span><span style="color: #007700">(</span><span style="color: #0000BB">null</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   
<div class="example-contents"><p>
 Результат выполнения приведённого примера:
</p></div>

   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
object(C)#1 (0) {
}
NULL
</pre></div>
   </div>
  </div>

  <div class="example" id="example-8">
   <p><strong>Пример #8 Объявление типа значения возврата как обнуляемого</strong></p>
   <div class="example-contents">
<div class="annotation-non-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">function </span><span style="color: #0000BB">get_item</span><span style="color: #007700">(): ?</span><span style="color: #0000BB">string<br /></span><span style="color: #007700">{<br />    if (isset(</span><span style="color: #0000BB">$_GET</span><span style="color: #007700">[</span><span style="color: #DD0000">'item'</span><span style="color: #007700">])) {<br />        return </span><span style="color: #0000BB">$_GET</span><span style="color: #007700">[</span><span style="color: #DD0000">'item'</span><span style="color: #007700">];<br />    } else {<br />        return </span><span style="color: #0000BB">null</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>

  <div class="example" id="example-9">
   <p><strong>Пример #9 Объявление типа свойства класса</strong></p>
   <div class="example-contents">
<div class="annotation-non-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">User<br /></span><span style="color: #007700">{<br />    public static </span><span style="color: #0000BB">string $foo </span><span style="color: #007700">= </span><span style="color: #DD0000">'foo'</span><span style="color: #007700">;<br /><br />    public </span><span style="color: #0000BB">int $id</span><span style="color: #007700">;<br />    public </span><span style="color: #0000BB">string $username</span><span style="color: #007700">;<br /><br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">(</span><span style="color: #0000BB">int $id</span><span style="color: #007700">, </span><span style="color: #0000BB">string $username</span><span style="color: #007700">)<br />    {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">id </span><span style="color: #007700">= </span><span style="color: #0000BB">$id</span><span style="color: #007700">;<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">username </span><span style="color: #007700">= </span><span style="color: #0000BB">$username</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </div>

 <div class="sect2" id="language.types.declarations.strict">
  <h3 class="title">Строгая типизация</h3>

  <p class="para">
   В нестрогом режиме, в котором проверка типов работает по умолчанию, PHP преобразовывает значения неправильного типа
   в скалярный тип, который указали в объявлении, поэтому, например, при передаче в параметр с типом <span class="type"><a href="language.types.string.php" class="type string">string</a></span>
   аргумента с типом <span class="type"><a href="language.types.integer.php" class="type int">int</a></span> функция получит значение с типом <span class="type"><a href="language.types.string.php" class="type string">string</a></span>.
  </p>

  <p class="para">
   Строгий режим включается отдельно для каждого файла. В строгом режиме
   механизм проверки типов признаёт только значения, которые соответствуют типу объявления,
   иначе выбрасывается ошибка <span class="classname"><a href="class.typeerror.php" class="classname">TypeError</a></span>.
   Единственное исключение из правила — значения с типом <span class="type"><a href="language.types.integer.php" class="type int">int</a></span>,
   которые передают в объявления типа <span class="type"><a href="language.types.float.php" class="type float">float</a></span>.
  </p>

  <div class="warning"><strong class="warning">Внимание</strong>
   <p class="simpara">
    Объявление директивы <code class="literal">strict_types</code> не влияет на вызовы функций внутри встроенных функций.
   </p>
  </div>

  <p class="para">
   Строгий режим включают инструкцией <a href="control-structures.declare.php" class="link"><code class="literal">declare</code></a> с объявлением
   директивы <code class="literal">strict_types</code>:
  </p>

  <blockquote class="note"><p><strong class="note">Замечание</strong>: 
   <p class="para">
    На строгость проверки типов при вызове функций влияет режим,
    который объявили <em>внутри</em> файла вызова,
    а не режим, который установили в файле объявления функции.
    Механизм проверки типов применит режим, который установили на стороне вызова,
    и автоматически приведёт типы значений, если файл без строгой типизации
    вызывает функцию, которую объявили в файле со строгой типизацией.
   </p>
  </p></blockquote>

  <blockquote class="note"><p><strong class="note">Замечание</strong>: 
   <p class="para">
    Строгая типизация определяется только для объявлений скалярных типов.
   </p>
  </p></blockquote>

  <div class="example" id="example-10">
   <p><strong>Пример #10 Строгая типизация для значений аргументов</strong></p>
   <div class="example-contents">
<div class="annotation-non-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">declare(</span><span style="color: #0000BB">strict_types</span><span style="color: #007700">=</span><span style="color: #0000BB">1</span><span style="color: #007700">);<br /><br />function </span><span style="color: #0000BB">sum</span><span style="color: #007700">(</span><span style="color: #0000BB">int $a</span><span style="color: #007700">, </span><span style="color: #0000BB">int $b</span><span style="color: #007700">)<br />{<br />    return </span><span style="color: #0000BB">$a </span><span style="color: #007700">+ </span><span style="color: #0000BB">$b</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">sum</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">2</span><span style="color: #007700">));<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">sum</span><span style="color: #007700">(</span><span style="color: #0000BB">1.5</span><span style="color: #007700">, </span><span style="color: #0000BB">2.5</span><span style="color: #007700">));<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   
<div class="example-contents"><p>
 Результат выполнения приведённого примера в PHP 8:
</p></div>

   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
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
</pre></div>
   </div>
  </div>

  <div class="example" id="example-11">
   <p><strong>Пример #11 Приведение типов для значений аргументов</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">function </span><span style="color: #0000BB">sum</span><span style="color: #007700">(</span><span style="color: #0000BB">int $a</span><span style="color: #007700">, </span><span style="color: #0000BB">int $b</span><span style="color: #007700">)<br />{<br />    return </span><span style="color: #0000BB">$a </span><span style="color: #007700">+ </span><span style="color: #0000BB">$b</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">sum</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">2</span><span style="color: #007700">));<br /><br /></span><span style="color: #FF8000">// Механизм проверки типов приведёт значения аргументов к целым числам: обратите внимание на вывод!<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">sum</span><span style="color: #007700">(</span><span style="color: #0000BB">1.5</span><span style="color: #007700">, </span><span style="color: #0000BB">2.5</span><span style="color: #007700">));<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   
<div class="example-contents"><p>
 Результат выполнения приведённого примера:
</p></div>

   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
int(3)
int(3)
</pre></div>
   </div>
  </div>

  <div class="example" id="example-12">
   <p><strong>Пример #12 Строгая типизация для значений возврата</strong></p>
   <div class="example-contents">
<div class="annotation-non-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">declare(</span><span style="color: #0000BB">strict_types</span><span style="color: #007700">=</span><span style="color: #0000BB">1</span><span style="color: #007700">);<br /><br />function </span><span style="color: #0000BB">sum</span><span style="color: #007700">(</span><span style="color: #0000BB">$a</span><span style="color: #007700">, </span><span style="color: #0000BB">$b</span><span style="color: #007700">): </span><span style="color: #0000BB">int<br /></span><span style="color: #007700">{<br />    return </span><span style="color: #0000BB">$a </span><span style="color: #007700">+ </span><span style="color: #0000BB">$b</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">sum</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">2</span><span style="color: #007700">));<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">sum</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">2.5</span><span style="color: #007700">));<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   
<div class="example-contents"><p>
 Результат выполнения приведённого примера:
</p></div>

   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
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
</pre></div>
   </div>
  </div>
 </div>

</div><?php manual_footer($setup); ?>