## Новые возможности

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

Типы параметров и значений возврата функций стали обнуляемыми. Тип становится обнуляемым, если перед названием типа указали вопросительный знак. Знак вопроса перед названием типа указывает, что параметр принимает, или функция возвращает, значение заданного типа или значение `null`.

    <?php

    function testReturnA(): ?string
    {
        return 'elePHPant';
    }

    var_dump(testReturnA());

    function testReturnB(): ?string
    {
        return null;
    }

    var_dump(testReturnB());

    function test(?string $name)
    {
        var_dump($name);
    }

    test('elePHPant');
    test(null);
    test();

    ?>

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

    string(9) "elePHPant"
    NULL
    string(9) "elePHPant"
    NULL
    Fatal error: Uncaught ArgumentCountError: Too few arguments to function test(), 0 passed in...

### Функции без возврата значения

Для значений возврата добавили тип void. В функциях с типом возврата void потребуется либо пропустить инструкцию return, либо указать пустую инструкцию return, без значения. Из void-функций нельзя возвращать значение `null`.

    <?php

    function swap(&$left, &$right): void
    {
        if ($left === $right) {
            return;
        }

        $tmp = $left;
        $left = $right;
        $right = $tmp;
    }

    $a = 1;
    $b = 2;
    var_dump(swap($a, $b), $a, $b);

    ?>

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

    null
    int(2)
    int(1)

При попытке получить возврат void-функции значение вычисляется как `null`, без выдачи предупреждения. Причина такого поведения состоит в том, что предупреждения ограничили бы работу общих функций высшего порядка с void-функциями.

### Симметричная деструктуризация массива

Короткий синтаксис массивов `[]` теперь доступен для деструктуризации массивов и присваивания значений, в том числе в циклах `foreach`. Короткий синтаксис появился как альтернатива языковой конструкции list(), которая по-прежнему поддерживается.

    <?php

    $data = [
        [1, 'Tom'],
        [2, 'Fred'],
    ];

    // Деструктуризация массива в стиле языковой конструкции list()
    list($id1, $name1) = $data[0];

    // Деструктуризация массива в стиле короткого синтаксиса массивов []
    [$id1, $name1] = $data[0];

    // Деструктуризация через list()
    foreach ($data as list($id, $name)) {
        // В этом месте применяем логику работы с переменными $id и $name
    }

    // Деструктуризация через короткий синтаксис []
    foreach ($data as [$id, $name]) {
        // В этом месте применяем логику работы с переменными $id и $name
    }

    ?>

### Видимость констант класса

Константы классов теперь поддерживают определение области видимости.

    <?php

    class ConstDemo
    {
        const PUBLIC_CONST_A = 1;
        public const PUBLIC_CONST_B = 2;
        protected const PROTECTED_CONST = 3;
        private const PRIVATE_CONST = 4;
    }

    ?>

### Псевдотип iterable

Семейство псевдотипов, к которым также относится тип callable, пополнилось новым псевдотипом с названием iterable. Новый псевдотип доступен и как тип параметров, и как тип значений возврата, которые принимают массивы или объекты, которые реализуют интерфейс Traversable. В вопросах подтипирования, типам параметров дочерних классов доступно расширение типа array или Traversable в объявлениях родительского класса до типа iterable. В объявлениях типа возврата дочерним классам разрешается сужать тип возврата родительского метода с iterable до array или Traversable.

    <?php

    function iterator(iterable $iter)
    {
        foreach ($iter as $val) {
            //
        }
    }

### Обработка набора исключений в одном блоке catch

Блоки catch научились обрабатывать набор исключений, которые указывают через символ вертикальной черты `|`. Это приносит пользу, когда исключения разных иерархий классов требуется обрабатывать одинаково.

    <?php

    try {
        // Какой-то код
    } catch (FirstException | SecondException $e) {
        // Обрабатываем одно или другое исключение
    }

### Поддержка ключей в языковой конструкции list()

Языковая конструкция list() и её новый короткий синтаксис `[]` теперь поддерживают ключи. Это помогает деструктурировать массивы с нечисловыми или непоследовательными ключами.

    <?php

    $data = [
        ["id" => 1, "name" => 'Tom'],
        ["id" => 2, "name" => 'Fred'],
    ];

    // Деструктуризация массива в стиле языковой конструкции list()
    list("id" => $id1, "name" => $name1) = $data[0];

    // Деструктуризация массива в стиле короткого синтаксиса массивов []
    ["id" => $id1, "name" => $name1] = $data[0];

    // Деструктуризация в стиле list()
    foreach ($data as list("id" => $id, "name" => $name)) {
        // Применяем логику обработки переменных $id и $name
    }

    // Деструктуризация в стиле короткого синтаксиса []
    foreach ($data as ["id" => $id, "name" => $name]) {
        // Применяем логику обработки переменных $id и $name
    }

    ?>

### Поддержка отрицательных смещений в строках

В функции для работы со строками, которые поддерживают смещения, и в работу с символами строки по индексу через короткий синтаксис массива `[]` или фигурные скобки `{}` добавили поддержку отрицательных смещений в строках. В функциях и при доступе к символам строки по индексу отрицательные смещения интерпретируются как смещения относительно конца строки.

    <?php

    var_dump("abcdef"[-2]);
    var_dump(strpos("aabbcc", "b", -3));

    ?>

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

    string (1) "e"
    int(3)

Отрицательные смещения в строках и массивах теперь также поддерживаются в простом синтаксисе разбора переменных внутри строк.

    <?php

    $string = 'bar';
    echo "Последний символ в строке '$string' — '$string[-1]'.\n";

    ?>

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

    Последний символ в строке 'bar' — 'r'.

### Поддержка режима AEAD в модуле OpenSSL

За счёт расширения функций openssl_encrypt() и openssl_decrypt() дополнительными параметрами добавили поддержку AEAD-режимов GCM и CCM.

### Преобразование значений с типом callable в тип Closure методом Closure::fromCallable()

В класс Closure добавили новый статический метод, который легко преобразовывает значения с типом callable в объекты класса Closure.

    <?php

    class Test
    {
        public function exposeFunction()
        {
            return Closure::fromCallable([$this, 'privateFunction']);
        }

        private function privateFunction($param)
        {
            var_dump($param);
        }
    }

    $privFunc = (new Test)->exposeFunction();
    $privFunc('значение');

    ?>

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

    string(16) "значение"

### Асинхронная обработка сигналов

Для асинхронной обработки сигналов в ядро PHP добавили функцию pcntl_async_signals(). Новая функция не использует механизм тиков, который вызывает избыточные накладные расходы.

    <?php

    pcntl_async_signals(true); // Включает асинхронные сигналы

    pcntl_signal(SIGHUP,  function($sig) {
        echo "SIGHUP\n";
    });

    posix_kill(posix_getpid(), SIGHUP);

    ?>

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

    SIGHUP

### Поддержка механизма HTTP/2 Server Push в модуле cURL

В модуль cURL добавили поддержку механизма Server Push. Для работы механизма требуется библиотека cURL версия 7.46 и выше. Поддержка заблаговременной отправки данных работает в функции curl_multi_setopt() с новой константой `CURLMOPT_PUSHFUNCTION`. В модуль также добавили константы `CURL_PUSH_OK` и `CURL_PUSH_DENY`, чтобы одобрить или отклонить выполнение Server Push в клиентской callback-функции.

### Контекстные опции потока

В контекст потока добавили параметр tcp_nodelay.

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open