Menu
Coddy logo textTech

Файберы (PHP 8.1)

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

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

Создай fiber, передав 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 выполняется, пока не достигает Fiber::suspend(), затем управление возвращается в основной код. Вызов resume() продолжает выполнение с места, где оно было приостановлено.

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

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

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

challenge icon

Задание

Легко

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

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

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

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

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

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

Это задание показывает, как fiber обеспечивает кооперативную многозадачность. Ваша задача приостанавливается в удобный момент, основной код выполняет другую работу, а затем возобновляет задачу с новыми данными. 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Проверьте себя

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

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

Потренируйтесь самостоятельно: Онлайн-компилятор PHP