Menu
CoddyTech

Fiber (PHP 8.1)

Thuộc phần Lập trình hướng đối tượng trong hành trình PHP của Coddy. Bài học 60 trên 91.

Fiber là tính năng của PHP 8.1 cho phép tạm dừng quá trình thực thi code. Khác với các hàm thông thường chạy từ đầu đến cuối, fiber có thể tự tạm dừng giữa chừng khi đang chạy và tiếp tục sau đó, đồng thời giữ nguyên trạng thái giữa các lần tạm dừng.

Tạo một fiber bằng cách truyền một đối tượng có thể gọi vào lớp Fiber, sau đó khởi chạy fiber bằng 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();

Đầu ra:

Step 1
Between steps
Step 2

Fiber chạy cho đến khi gặp Fiber::suspend(), sau đó quyền điều khiển quay lại đoạn code chính. Gọi resume() sẽ tiếp tục thực thi từ nơi đã tạm dừng.

Fiber cũng có thể truyền giá trị khi tạm dừng và tiếp tục:

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

Đầu ra:

paused
Received: hello

Fiber là nền tảng của các framework PHP bất đồng bộ. Dù bạn sẽ không trực tiếp dùng chúng trong hầu hết ứng dụng, việc hiểu về chúng sẽ giúp bạn làm việc với các thư viện bất đồng bộ xử lý đồng thời những thao tác như yêu cầu HTTP hoặc truy vấn cơ sở dữ liệu mà không chặn chương trình.

challenge icon

Thử thách

Dễ

Hãy xây dựng một bộ lập lịch tác vụ để minh họa cách fiber có thể tạm dừng và tiếp tục thực thi, đồng thời truyền dữ liệu giữa fiber và code chính. Bạn sẽ tạo một hệ thống cho phép ngắt các tác vụ để thực hiện công việc khác xen kẽ.

Bạn sẽ sắp xếp code trong hai tệp:

  • TaskRunner.php: Tạo một lớp TaskRunner bao bọc chức năng của fiber để chạy tác vụ. Lớp này cần:
    • Có một thuộc tính riêng để lưu một instance Fiber
    • Nhận tên tác vụ (chuỗi) trong hàm khởi tạo bằng cách dùng tính năng khởi tạo thuộc tính trong hàm khởi tạo
    • Có phương thức createTask(callable $task) để tạo một Fiber mới với callable đã cho và lưu Fiber đó
    • Có phương thức start() để bắt đầu fiber và trả về giá trị mà fiber tạm dừng cùng (hoặc giá trị trả về cuối cùng)
    • Có phương thức continue(mixed $value) để tiếp tục fiber với giá trị đã cho và trả về giá trị tạm dừng tiếp theo (hoặc giá trị trả về cuối cùng)
    • Có phương thức isFinished(): bool để trả về trạng thái fiber đã kết thúc hay chưa
  • main.php: Nạp tệp TaskRunner. Bạn sẽ nhận hai đầu vào: tên tác vụ và một thông điệp để gửi cho fiber.

    Tạo một TaskRunner với tên tác vụ đã cho, sau đó dùng createTask() để định nghĩa một tác vụ:

    1. Đầu tiên, tạm dừng với chuỗi "Waiting for input"
    2. Nhận một giá trị khi được tiếp tục
    3. Trả về "Completed: [received value]"

    Bắt đầu tác vụ và in ra giá trị mà tác vụ trả về khi tạm dừng lần đầu. Sau đó, in ra "Processing..." để cho thấy công việc diễn ra trong lúc fiber tạm dừng. Cuối cùng, tiếp tục fiber bằng cách truyền đầu vào thông điệp, rồi in ra kết quả cuối cùng.

Thử thách này cho thấy fiber cho phép đa nhiệm hợp tác như thế nào. Tác vụ tự tạm dừng tại một thời điểm thích hợp, code chính thực hiện công việc khác, rồi tiếp tục tác vụ với dữ liệu mới. Fiber duy trì trạng thái trong suốt quá trình và tiếp tục chính xác từ nơi đã tạm dừng.

Tự làm thử

<?php

require_once 'TaskRunner.php';

// Đọc các đầu vào
$taskName = trim(fgets(STDIN));
$message = trim(fgets(STDIN));

// TODO: Tạo TaskRunner với tên tác vụ đã cho

// TODO: Dùng createTask() để định nghĩa một tác vụ:
// 1. Đầu tiên tạm dừng với chuỗi "Waiting for input"
// 2. Nhận một giá trị khi tiếp tục chạy
// 3. Trả về "Completed: [received value]"

// TODO: Bắt đầu tác vụ và in ra giá trị trả về khi tác vụ tạm dừng lần đầu

// TODO: In ra "Processing..." để cho thấy công việc diễn ra giữa các lần fiber tạm dừng

// TODO: Tiếp tục fiber bằng cách truyền đầu vào message vào

// TODO: In ra kết quả cuối cùng

?>
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch PHP online