(PHP 8 >= 8.1.0)
Файберы — механизм управления функциями, который умеет прерывать выполнение функций с сохранением полного внутреннего стека вызовов. Файберы разрешается приостанавливать в произвольном месте внутреннего стека вызовов, при этом выполнение кода внутри файбера приостанавливается, пока файбер не возобновит работу.
Файберы приостанавливают весь внутренний стек выполнения, поэтому коду, который работает с файберами, не придётся изменять логику вызова методов файбера (тогда как в других языках программирования при взаимодействии с асинхронными сопрограммами вызывающий код вынужденно изменяет способ вызова функций — прим. перев.).
Выполнение файбера разрешается прерывать методом Fiber::suspend() в произвольном месте стека вызовов, вызвать метод Fiber::suspend() можно в глубоко вложенной функции или не вызывать вовсе.
В отличие от бесстековых Generator'ов, под каждый Fiber
внутренне выделяется отдельный стек вызовов, что разрешает приостанавливать стеки внутри глубоко вложенных вызовов функций.
Функция, которая вызовом метода Fiber::suspend() объявляет точку прерывания файбера,
не изменяет тип значения, которое она возвращает, в отличие от функций, которые содержат ключевое слово yield
и потому возвращают экземпляр класса Generator.
Приостановка файберов доступна как в пользовательских функциях, так и в функциях,
которые вызываются внутри виртуальной машины языка PHP, наподобие callback-функции,
которую передают как аргумент функции array_map(), или методов, которые цикл foreach
вызывает на объекте класса Iterator.
Выполнение приостановленного файбера возобновляют либо вызовом метода Fiber::resume(), который умеет передавать в точку приостановки файбера произвольное значение, либо вызовом метода Fiber::throw(), который передаёт исключение в ту же точку. При возобновлении работы файбера с передачей значения это значение возвращается в точке прерывания файбера как результат вызова метода Fiber::suspend(), а при передаче исключения — файбер возобновляет выполнение в той же точке и выбрасывает это исключение.
Замечание: До PHP 8.4.0 запрещалось переключать файбер в деструкторе объекта.
Пример #1 Стандартный пример работы с файбером
<?php
$fiber = new Fiber(function (): void {
$value = Fiber::suspend('fiber');
echo "Значение возобновлённого файбера: ", $value, PHP_EOL;
});
$value = $fiber->start();
echo "Значение приостановленного файбера: ", $value, PHP_EOL;
$fiber->resume('test');
?>
Результат выполнения приведённого примера:
Значение приостановленного файбера: fiber Значение возобновлённого файбера: test