Coroutines trong PHP


1. Mở đầu
Bạn từng nghe đến function
, loop
, yield
, nhưng đã bao giờ tưởng tượng một hàm có thể “nghỉ ngơi giữa chừng” rồi “tỉnh dậy tiếp tục” như thể vừa ngủ vừa làm việc? Đó chính là coroutine – khái niệm thú vị giúp viết code không đồng bộ (asynchronous) hiệu quả hơn. Với PHP, hiểu coroutine sẽ giúp bạn làm việc với CLI tool, pipeline hay async code dễ dàng hơn.
2. Coroutines là gì? (Từ cơ bản đến nâng cao)
Giải thích đơn giản
- Hàm bình thường: chạy từ đầu đến cuối, rồi kết thúc.
- Coroutine: là hàm có thể tạm dừng giữa chừng (suspend), giữ nguyên trạng thái và sau đó được tiếp tục (resume). Khi tạm dừng, coroutine có thể “trả” một giá trị và khi được gọi lại, có thể “nhận” một giá trị nữa. Nó giống như một cuộc hội thoại hai chiều giữa hàm và phần gọi nó (doeken.org).
So sánh sống động:
- Subroutine (hàm thường) như một nhân viên làm việc liên tục từ đầu đến cuối.
- Coroutine như một nhân viên làm việc theo ca: tạm nghỉ, giữ nguyên công việc đang dở, rồi khi được gọi lại thì tiếp tục từ chỗ dừng.
Một ví dụ minh hoạ đơn giản
<?php
function sleepyCounter() {
for ($i = 1; $i <= 3; $i++) {
yield $i; // Tạm thời trả về $i và giữ trạng thái
}
}
$ctr = sleepyCounter();
echo $ctr->current(); // 1
$ctr->next();
echo $ctr->current(); // 2
$ctr->next();
echo $ctr->current(); // 3
- Hàm
sleepyCounter
là một coroutine dùngyield
. - Mỗi lần gọi
$ctr->next()
thì coroutine “thức dậy” và trả giá trị tiếp theo.
3. Coroutines trong PHP dùng thế nào? (Generators và Fibers)
PHP hỗ trợ coroutine qua hai công cụ chính:
• Generators
- Ra đời từ PHP 5.5.
- Dùng
yield
để tạo hàm “nghỉ ngơi giữa chừng”. - Tiện ích: tiết kiệm bộ nhớ khi xử lý tập dữ liệu lớn như stream, file, số liệu,... (npopov.com, DEV Community).
Ví dụ thực tế 1:
Xử lý file hàng triệu dòng mà không cần tải cả file vào bộ nhớ, chỉ cần lần lượt yield
từng dòng xử lý.
Ví dụ thực tế 2: In ra dãy số Fibonacci vô hạn, nhưng chỉ cần dùng đến n phần tử đầu: generator cho phép tạo luồng số theo nhu cầu.
• Fibers
- Được thêm vào PHP 8.1.
- Cho phép một hàm dễ
suspend
vàresume
, thậm chí giữa các hàm gọi lồng nhau (amitmerchant.com, Blackfire.io Le Blog).
Ví dụ minh họa:
$fiber = new Fiber(function(): void {
$value = Fiber::suspend('hello');
echo "Fiber resumed with: $value\n";
});
$returned = $fiber->start(); // trả về 'hello'
$fiber->resume('world'); // hàm in: Fiber resumed with: world
start()
bắt đầu coroutine, trả về giá trị khi suspend.resume()
tiếp tục coroutine từ chỗ dừng với giá trị mới.
4. Ứng dụng thực tế & ví dụ minh hoạ
Ví dụ 1: Pipeline đơn giản
function pipeline() {
$data = yield readData();
yield processData($data);
yield saveData();
}
- Mỗi
yield
là bước dừng lại để đợi dữ liệu đọc xong, xử lý xong rồi lưu xong.
Ví dụ 2: Du lịch theo tuyến (analogy)
Hãy tưởng tượng bạn đi du lịch và có thể dừng ở mỗi thành phố, ngắm cảnh, rồi mới tiếp tục đi tiếp – giống coroutine “nghỉ ngơi” giữa chuyến đi mà vẫn nhớ đang ở đâu.
5. Tương tác nhẹ (Thử thách nhỏ)
Tưởng tượng bạn cần xử lý dòng lệnh nhập vào từng dòng, rồi in ngược lại từng dòng. Bạn sẽ dùng generator như thế nào?
Nếu muốn hai coroutine chạy xen kẽ, mỗi coroutine làm một phần việc (ví dụ đếm từ 1–5 và in chữ), làm sao tạo scheduler đơn giản để luân phiên gọi lại?
6. Kết luận & kinh nghiệm
Tóm tắt:
- Coroutines là hàm có khả năng tạm dừng và tiếp tục, giữ trạng thái.
- PHP hỗ trợ qua Generators (PHP 5.5+) và Fibers (PHP 8.1+).
- Phù hợp với xử lý luồng dữ liệu, CLI tools, async workflows.
Tips cho bạn mới:
- Bắt đầu từ generator – đơn giản, dễ hiểu và hỗ trợ PHP rộng rãi.
- Khi cần kiểm soát sâu hơn, chuyển sang Fiber.
- Luôn thử nghiệm từng bước nhỏ với ví dụ thú vị – code ngắn, có comment tiếng Việt giúp bạn hiểu rõ hơn.
Tài liệu tham khảo thêm
- Doeke Norg – Exploring Coroutines in PHP (4 Jul 2025) (doeken.org)
- Nikic – Cooperative multitasking using coroutines in PHP (npopov.com)
- Amit Merchant – Fibers và Coroutines PHP 8.1 (amitmerchant.com)
- Blackfire blog – Cách PHP profile coroutines (Blackfire.io Le Blog)
Chúc bạn học vui và “coroutine-fun” nhé! Khi bạn thử viết mã, mình luôn sẵn lòng hỗ trợ thêm.
Subscribe to my newsletter
Read articles from Binlerdev directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
