Menu
Coddy logo textTech

Файберы (PHP 8.1)

Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy — урок 60 из 91.

Файберы (Fibers) — это функция PHP 8.1, позволяющая прерывать выполнение кода. В отличие от обычных функций, которые выполняются от начала до конца, файбер может приостановить свое выполнение в середине и возобновить его позже, сохраняя свое состояние между паузами.

Создайте фабер, передав callable в класс Fiber, затем запустите его с помощью start():

<?php
$fiber = new Fiber(function(): void {
    echo "Step 1\n";
    Fiber::suspend();
    echo "Step 2\n";
});

$fiber->start();
echo "Between steps\n";
$fiber->resume();

Вывод:

Step 1
Between steps
Step 2

Файбер выполняется до тех пор, пока не достигнет Fiber::suspend(), после чего управление возвращается в основной код. Вызов resume() продолжает выполнение с места его остановки.

Файберы также могут передавать значения при приостановке и возобновлении:

<?php
$fiber = new Fiber(function(): string {
    $value = Fiber::suspend("paused");
    return "Received: $value";
});

$suspended = $fiber->start();
echo "$suspended\n";

$result = $fiber->resume("hello");
echo $result;

Вывод:

paused
Received: hello

Файберы (Fibers) являются основой для асинхронных PHP-фреймворков. Хотя в большинстве приложений вы не будете использовать их напрямую, понимание того, как они работают, помогает при работе с асинхронными библиотеками, которые обрабатывают параллельные операции, такие как HTTP-запросы или запросы к базе данных, без блокировки.

challenge icon

Задание

Легко

Давайте построим планировщик задач, который демонстрирует, как fibers могут приостанавливать и возобновлять выполнение, передавая данные между fiber и основным кодом. Вы создадите систему, в которой задачи могут быть прерваны, позволяя другой работе выполняться в промежутке.

Вы организуете свой код в двух файлах:

  • TaskRunner.php — Создайте класс TaskRunner, который обертывает функциональность fiber для запуска задач. Класс должен:
    • Иметь private свойство для хранения экземпляра Fiber
    • Принимать имя задачи (string) в своем конструкторе с использованием продвижения свойств в конструкторе (constructor promotion)
    • Иметь метод createTask(callable $task), который создает новый Fiber с переданным callable и сохраняет его
    • Иметь метод start(), который запускает fiber и возвращает любое значение, с которым fiber приостанавливает работу (или итоговое возвращаемое значение)
    • Иметь метод continue(mixed $value), который возобновляет fiber с переданным значением и возвращает следующее приостановленное значение (или итоговое возвращаемое значение)
    • Иметь метод isFinished(): bool, который возвращает, завершил ли fiber работу
  • main.php — Подключите файл TaskRunner. Вы получите два входных значения: имя задачи и сообщение для отправки в fiber.

    Создайте TaskRunner с заданным именем задачи, затем используйте createTask(), чтобы определить задачу, которая:

    1. Сначала приостанавливается со строкой "Waiting for input"
    2. Получает значение при возобновлении
    3. Возвращает "Completed: [received value]"

    Запустите задачу и выведите то, что она возвращает при первой приостановке. Затем выведите "Processing...", чтобы показать работу, происходящую между паузами fiber. Наконец, продолжите выполнение fiber, передав введенное сообщение, и выведите итоговый результат.

Это задание показывает, как fibers обеспечивают кооперативную многозадачность — ваша задача приостанавливает себя в удобный момент, основной код выполняет другую работу, а затем возобновляет задачу с новыми данными. Fiber сохраняет свое состояние на всем протяжении, продолжая работу ровно с того места, где остановился.

Попробуйте сами

<?php

require_once 'TaskRunner.php';

// Читать входные данные
$taskName = trim(fgets(STDIN));
$message = trim(fgets(STDIN));

// TODO: Создайте TaskRunner с заданным именем задачи

// TODO: Используйте createTask() для определения задачи, которая:
// 1. First suspends with the string "Waiting for input"
// 2. Получает значение при возобновлении
// 3. Возвращает "Completed: [received value]"

// TODO: Запустите задачу и выведите то, что она возвращает при первой приостановке

// TODO: Выведите "Processing...", чтобы показать работу между паузами fiber

// TODO: Продолжите fiber, передав входное сообщение

// TODO: Выведите конечный результат

?>
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование