mirror of
https://github.com/php/doc-ru.git
synced 2026-03-24 07:42:22 +01:00
844 lines
26 KiB
XML
844 lines
26 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- EN-Revision: 0ece873cecfc4dacd14e8bebbec12c6e00de56a0 Maintainer: rjhdby Status: ready -->
|
||
<!-- Reviewed: no -->
|
||
<sect1 xml:id="language.types.declarations">
|
||
<title>Объявления типов</title>
|
||
|
||
<para>
|
||
Объявления типов добавляют параметрам функций, значениям возврата,
|
||
начиная с PHP 7.4.0 свойствам класса и начиная с PHP 8.3.0 константам класса.
|
||
Объявления типов гарантируют, что при вызове значение принадлежит заданному типу,
|
||
иначе PHP выбросит ошибку <classname>TypeError</classname>.
|
||
</para>
|
||
|
||
<para>
|
||
Каждый тип, который поддерживает PHP, за исключением ресурсов (<type>resource</type>),
|
||
разрешается указывать в пользовательском объявлении типа.
|
||
Страница содержит журнал изменений доступности отдельных типов
|
||
и документацию, которая описывает правила объявления типов.
|
||
</para>
|
||
|
||
<note>
|
||
<para>
|
||
Класс, который реализует метод интерфейса или переопределяет метод
|
||
родительского класса,
|
||
подчиняется правилам совместимости.
|
||
Метод совместим, если следует
|
||
<link linkend="language.oop5.variance">правилам вариантности</link>.
|
||
</para>
|
||
</note>
|
||
|
||
<sect2 role="changelog">
|
||
&reftitle.changelog;
|
||
<informaltable>
|
||
<tgroup cols="2">
|
||
<thead>
|
||
<row>
|
||
<entry>&Version;</entry>
|
||
<entry>&Description;</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>8.3.0</entry>
|
||
<entry>
|
||
Добавили поддержку типизации констант классов, интерфейсов, трейтов и перечислений.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>8.2.0</entry>
|
||
<entry>
|
||
Добавили поддержку <acronym>DNF</acronym>-типов.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>8.2.0</entry>
|
||
<entry>
|
||
Добавили поддержку самостоятельного типа <type>true</type>.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>8.2.0</entry>
|
||
<entry>
|
||
Типы <type>null</type> и <type>false</type> разрешили указывать отдельно.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>8.1.0</entry>
|
||
<entry>
|
||
Добавили поддержку пересечений типов.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>8.1.0</entry>
|
||
<entry>
|
||
Возврат по ссылке из функции с типом значения возврата <type>void</type> устарел.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>8.1.0</entry>
|
||
<entry>
|
||
Для значения возврата добавили поддержку типа <type>never</type>.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>8.0.0</entry>
|
||
<entry>
|
||
Для значения возврата добавили поддержку типа <type>mixed</type>.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>8.0.0</entry>
|
||
<entry>
|
||
Для значения возврата добавили поддержку типа <type>static</type>.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>8.0.0</entry>
|
||
<entry>
|
||
Добавили поддержку объединения типов.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>7.4.0</entry>
|
||
<entry>
|
||
Добавили поддержку типизации свойств классов.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>7.2.0</entry>
|
||
<entry>
|
||
Для значения возврата добавили поддержку типа <type>object</type>.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>7.1.0</entry>
|
||
<entry>
|
||
Для значения возврата добавили поддержку типа <type>iterable</type>.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>7.1.0</entry>
|
||
<entry>
|
||
Для значения возврата добавили поддержку типа <type>void</type>.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>7.1.0</entry>
|
||
<entry>
|
||
Для значения возврата добавили поддержку обнуляемого типа.
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</sect2>
|
||
|
||
<sect2 xml:id="language.types.declarations.base">
|
||
<title>Атомарные типы</title>
|
||
|
||
<simpara>
|
||
Атомарные типы ведут себя прямолинейно, но с рядом оговорок,
|
||
которые описывает этот раздел.
|
||
</simpara>
|
||
|
||
<sect3 xml:id="language.types.declarations.base.scalar">
|
||
<title>Скалярные типы</title>
|
||
<warning>
|
||
<para>
|
||
Псевдонимы имён для скалярных типов, к которым относятся типы <type>bool</type>, <type>int</type>,
|
||
<type>float</type> и <type>string</type>, не поддерживаются.
|
||
Вместо назначения псевдонимов названия классов и интерфейсов трактуются как типы.
|
||
Например, буквальное название <literal>boolean</literal> в объявлении типа потребует,
|
||
чтобы значение выполняло условие &instanceof; в отношении класса или интерфейса
|
||
<literal>boolean</literal>, а не принадлежало типу <type>bool</type>:
|
||
</para>
|
||
<informalexample>
|
||
<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>
|
||
</informalexample>
|
||
</warning>
|
||
</sect3>
|
||
|
||
<sect3 xml:id="language.types.declarations.void">
|
||
<title>Тип void</title>
|
||
<note>
|
||
<para>
|
||
Возврат по ссылке из <type>void</type>-функции устарел начиная с PHP 8.1.0,
|
||
поскольку такая функция противоречива.
|
||
Раньше при вызове такой функции уже выдавалась ошибка уровня <constant>E_NOTICE</constant>:
|
||
<computeroutput>Только ссылки на переменные должны возвращаться по ссылке</computeroutput>.
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
function &test(): void {}
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</para>
|
||
</note>
|
||
</sect3>
|
||
|
||
<sect3 xml:id="language.types.declarations.base.function">
|
||
<title>Тип Callable</title>
|
||
<para>
|
||
Свойствам класса нельзя объявлять тип callable.
|
||
</para>
|
||
|
||
<note>
|
||
<simpara>
|
||
Тип callable нельзя указывать как название функции.
|
||
</simpara>
|
||
</note>
|
||
</sect3>
|
||
|
||
<sect3 xml:id="language.types.declarations.references">
|
||
<title>Объявление типов параметрам, которые принимают ссылку</title>
|
||
|
||
<simpara>
|
||
Параметр, который принимает ссылку, проверяет
|
||
тип переменной <emphasis>только</emphasis> при входе в функцию, в начале вызова,
|
||
но не при возврате из функции,
|
||
поэтому в функции возможно изменение типа ссылки на переменную.
|
||
</simpara>
|
||
<example>
|
||
<title>Типизированный параметр, который принимает ссылку</title>
|
||
<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.similar;
|
||
<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>
|
||
</sect3>
|
||
</sect2>
|
||
|
||
<sect2 xml:id="language.types.declarations.composite">
|
||
<title>Примечание по составным типам</title>
|
||
<para>
|
||
На объявления составных типов распространяется ряд ограничений;
|
||
компилятор выполняет проверку избыточности типов,
|
||
чтобы предотвратить простые ошибки.
|
||
</para>
|
||
|
||
<caution>
|
||
<simpara>
|
||
Комбинирование пересечений и объединений типов оставалось невозможным
|
||
до PHP 8.2.0 и введения DNF-типов.
|
||
</simpara>
|
||
</caution>
|
||
|
||
<sect3 xml:id="language.types.declarations.composite.union">
|
||
<title>Объединение типов</title>
|
||
<warning>
|
||
<simpara>
|
||
Невозможно определить в объединённом типе два одноэлементных типа <type>false</type> и <type>true</type>.
|
||
Вместо этого указывают тип <type>bool</type>.
|
||
</simpara>
|
||
</warning>
|
||
|
||
<caution>
|
||
<simpara>
|
||
До PHP 8.2.0 запрещали определять типы <type>false</type> и <type>null</type> отдельно,
|
||
поэтому объединение типов, которое состояло только из этих типов, оставалось недопустимым.
|
||
К таким объединениям относятся типы: <type>false</type>, <literal>false|null</literal>
|
||
и <literal>?false</literal>.
|
||
</simpara>
|
||
</caution>
|
||
|
||
<sect4 xml:id="language.types.declarations.nullable">
|
||
<title>Синтаксический сахар обнуляемого типа</title>
|
||
|
||
<para>
|
||
Объявление отдельного базового типа помечают как nullable путём
|
||
добавления к типу префикса в виде
|
||
вопросительного знака (<literal>?</literal>).
|
||
Поэтому типы <literal>?T</literal> и <literal>T|null</literal> идентичны.
|
||
</para>
|
||
|
||
<note>
|
||
<simpara>
|
||
Этот синтаксис поддерживается с PHP 7.1.0
|
||
и предшествует поддержке объединения типов.
|
||
</simpara>
|
||
</note>
|
||
|
||
<note>
|
||
<para>
|
||
Ещё один способ объявить nullable-параметр —
|
||
указать значением по умолчанию значение <literal>null</literal>.
|
||
Объявлять тип таким способом не рекомендуют, поскольку изменение значения по умолчанию
|
||
в дочернем классе нарушит совместимость типов,
|
||
и к объявлению типа потребуется добавить тип <type>null</type>.
|
||
Это поведение также устарело начиная с PHP 8.4.
|
||
</para>
|
||
<example>
|
||
<title>Старый способ указать nullable-параметр</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>
|
||
</sect4>
|
||
</sect3>
|
||
|
||
<sect3 xml:id="language.types.declarations.composite.redundant">
|
||
<title>Повторные и избыточные типы</title>
|
||
<para>
|
||
Правила объявления составных типов предусматривают ряд ограничений.
|
||
При компиляции кода с избыточными типами, которые возможно обнаружить без загрузки классов,
|
||
возникнет ошибка. Примеры ошибок в объявлениях составных типов включают:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara>
|
||
Повторение типа в объявлениях наподобие <literal>int|string|INT</literal>
|
||
или <literal>Countable&Traversable&COUNTABLE</literal> вызовет ошибку,
|
||
поскольку после разрешения названия типа внутренними средствами языка тип встретится больше одного раза.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
Объявление типа <type>mixed</type> или <type>never</type> с другими типами вызовет ошибку.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>Ошибки объединения типов:</simpara>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara>
|
||
Избыточное объявление типа <type>false</type> или <type>true</type>
|
||
вместе с типом <type>bool</type>.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
Избыточное объявление типа класса вместе с типом <type>object</type>.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
Избыточное объявление типа <type>array</type> или <classname>Traversable</classname>
|
||
вместе с типом <type>iterable</type>.
|
||
</simpara>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>Ошибки пересечения типов:</simpara>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara>
|
||
Объявление типа, который не относится к классовому типу.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
Объявление типа <type>self</type>, <type>parent</type>
|
||
или <type>static</type>.
|
||
</simpara>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>Ошибки объявления <acronym>DNF</acronym>-типов:</simpara>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara>
|
||
Избыточное объявление более строго типа с более общим типом.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
Объявление дубликатов в пересечении типов.
|
||
</simpara>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</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 {} // Запрещено
|
||
function foo(): int&Traversable {} // Запрещено
|
||
function foo(): self&Traversable {} // Запрещено
|
||
|
||
use A as B;
|
||
function foo(): A|B {} // Запрещено (оператор "use" только создаёт псевдоним через механизм разрешения имён, а не отдельный тип)
|
||
function foo(): A&B {} // Запрещено (оператор "use" только создаёт псевдоним через механизм разрешения имён, а не отдельный тип)
|
||
|
||
class_alias('X', 'Y');
|
||
function foo(): X|Y {} // Разрешено (избыточность обнаружится только при выполнении кода)
|
||
function foo(): X&Y {} // Разрешено (избыточность обнаружится только при выполнении кода)
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</para>
|
||
</sect3>
|
||
</sect2>
|
||
|
||
<sect2 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;
|
||
}
|
||
|
||
// Обратите внимание, что функция вернёт значение с типом float
|
||
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>
|
||
|
||
<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" annotations="non-interactive">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
function get_item(): ?string
|
||
{
|
||
if (isset($_GET['item'])) {
|
||
return $_GET['item'];
|
||
} else {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<example>
|
||
<title>Объявление типа свойства класса</title>
|
||
<programlisting role="php" annotations="non-interactive">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
class User
|
||
{
|
||
public static string $foo = 'foo';
|
||
|
||
public int $id;
|
||
public string $username;
|
||
|
||
public function __construct(int $id, string $username)
|
||
{
|
||
$this->id = $id;
|
||
$this->username = $username;
|
||
}
|
||
}
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</sect2>
|
||
|
||
<sect2 xml:id="language.types.declarations.strict">
|
||
<title>Строгая типизация</title>
|
||
|
||
<para>
|
||
В нестрогом режиме, в котором проверка типов работает по умолчанию, PHP преобразовывает значения неправильного типа
|
||
в скалярный тип, который указали в объявлении, поэтому, например, при передаче в параметр с типом <type>string</type>
|
||
аргумента с типом <type>int</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" annotations="non-interactive">
|
||
<![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" annotations="non-interactive">
|
||
<![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>
|
||
|
||
</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
|
||
-->
|