mirror of
https://github.com/php/doc-ru.git
synced 2025-08-16 18:22:04 +00:00

git-svn-id: https://svn.php.net/repository/phpdoc/ru/trunk@351812 c90b9560-bf6c-de11-be94-00142212c4b1
819 lines
27 KiB
XML
819 lines
27 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- $Revision$ -->
|
||
<!-- EN-Revision: 1ffbadf2906a5c85d2f9437b87da3e204ea41b7a 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.mixed">
|
||
<title>mixed</title>
|
||
|
||
<para>
|
||
<type>mixed</type> эквивалентен <link linkend="language.types.declarations.union">типу union</link>
|
||
<type class="union">
|
||
<type>array</type><type>bool</type><type>callable</type><type>int</type><type>float</type>
|
||
<type>object</type><type>resource</type><type>string</type><type>null</type>
|
||
</type>.
|
||
Доступно с PHP 8.0.0.
|
||
</para>
|
||
</sect3>
|
||
|
||
<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
|
||
-->
|