Menu
Coddy logo textTech

Файберы (PHP 8.1)

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

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

Создайте файбер (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::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) могут приостанавливать и возобновлять выполнение, передавая данные между файбером и основным кодом. Вы создадите систему, в которой задачи могут прерываться, позволяя выполнять другую работу в промежутках.

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

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

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

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

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

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

Шпаргалка

Файберы (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();

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

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

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

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

Основные методы:

  • start() — начинает выполнение файбера
  • Fiber::suspend($value) — приостанавливает выполнение и возвращает значение вызывающей стороне
  • resume($value) — продолжает выполнение и передает значение в файбер
  • isTerminated() — проверяет, завершилось ли выполнение файбера

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

<?php

require_once 'TaskRunner.php';

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

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

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

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

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

// TODO: Продолжить выполнение файбера, передав входное сообщение message

// TODO: Вывести финальный результат

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

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

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