PHP: Объявление типов - Manual PHP Russia 2021


    Манипуляции с типами »
    « Функции обратного вызова (callback-функции)

    Submit a Pull Request Report a Bug

    Объявление типов

    Объявления типов могут использоваться для аргументов функций, возвращаемых значений и, начиная с PHP 7.4.0, для свойств класса. Они используются во время исполнения для проверки, что значение имеет точно тот тип, который для них указан. В противном случае будет выброшено исключение TypeError.

    Замечание:

    При переопределении родительского метода, тип возвращаемого значения дочернего метода должен соответствовать любому объявлению возвращаемого типа родительского. Если в родительском методе тип возвращаемого значения не объявлен, то это можно сделать в дочернем.

    Одиночные типы

    Тип Описание Версия
    Имя класса/интерфейса Значение должно представлять собой
        function test(boolean $param) {}
        test(true);

    Результат выполнения данного примера в PHP 8:


    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


    mixed

    mixed эквивалентен типу union array|bool|callable|int|float |object|resource|string|null . Доступно с PHP 8.0.0.


    Примеры

    Пример #1 Объявление типа для класса

    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);

    Результат выполнения данного примера в PHP 8:


    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

    Пример #2 Объявление типа для интерфейса

    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);

    Результат выполнения данного примера в PHP 8:


    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

    Пример #3 Объявление типа возвращаемого значения

    function sum($a, $b): float {
        return $a + $b;
    }
    // Обратите внимание, что будет возвращено число с плавающей точкой.
    var_dump(sum(1, 2));

    Результат выполнения данного примера:


    float(3)

    Пример #4 Возвращение объекта

    class C {}
    function getC(): C {
        return new C;
    }
    var_dump(getC());

    Результат выполнения данного примера:


    object(C)#1 (0) {
    }

    Обнуляемые типы

    Начиная с PHP 7.1.0, объявления типов могут быть помечены как обнуляемые, путём добавления префикса в виде знака вопроса(

    class C {}
    function f(?C $c) {
        var_dump($c);
    }
    f(new C);
    f(null);

    Результат выполнения данного примера:


    object(C)#1 (0) {
    }
    NULL

    Пример #6 Обнуляемые типы для возвращаемого значения

    function get_item(): ?string {
        if (isset($_GET['item'])) {
            return $_GET['item'];
        } else {
            return null;
        }
    }

    Замечание:

    До PHP 7.1.0, было возможно задавать обнуляемые типы аргументов функций путём задания значения по умолчанию равного

    class C {}
    function f(C $c = null) {
        var_dump($c);
    }
    f(new C);
    f(null);

    Результат выполнения данного примера:


    object(C)#1 (0) {
    }
    NULL


    Объединённые типы

    Объединённые типы позволяют использовать несколько типов, а не исключительно один. Для их объявления используется следующий синтаксис

    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 {} // Допустимо (повторение будет определено только во время выполнения)


    Типы, подходящие только для возвращаемого значения

    void

    Тип

    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));

    Результат выполнения данного примера в PHP 8:


    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

    Пример #9 Приведение типов для значений аргументов

    function sum(int $a, int $b) {
        return $a + $b;
    }
    var_dump(sum(1, 2));
    // Переданные значения будут приведены к целым числам: обратите внимание на вывод ниже!
    var_dump(sum(1.5, 2.5));

    Результат выполнения данного примера:


    int(3)
    int(3)

    Пример #10 Строгая типизация для возвращаемых значений

    declare(strict_types=1);
    function sum($a, $b): int {
        return $a + $b;
    }
    var_dump(sum(1, 2));
    var_dump(sum(1, 2.5));

    Результат выполнения данного примера:


    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

    Приведение для объединённых типов

    Если

    // 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

    Дополнительно

    Пример #12 Типизированные параметры передаваемые по ссылке

    Объявление типов для параметров передаваемых по ссылке проверяется только на этапе вызова функции. Не никакой гарантии, что после выхода из функции тип переменной останется неизменным.


    function array_baz(array &$param)
    {
        $param = 1;
    }
    $var = [];
    array_baz($var);
    var_dump($var);
    array_baz($var);

    Результат выполнения данного примера в PHP 8:


    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

    Пример #13 Обработка TypeError

    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();
    }

    Результат выполнения данного примера в PHP 8:


    int(3)
    Ошибка: sum(): Argument #1 ($a) must be of type int, float given, called in - on line 10

    User Contributed Notes


    There are no user contributed notes for this page.



    Смотрите также:
    Описание на ru2.php.net
    Описание на php.ru