Perulangan Peristiwa dengan ReactPHP
Jalankan I/O tanpa pemblokiran dengan perulangan peristiwa ReactPHP.
Perulangan Peristiwa dengan ReactPHP adalah pelajaran PHP Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar PHP Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus PHP Academy mencakup 4 pelajaran total.
ReactPHP dalam Satu Kalimat
ReactPHP adalah perangkat murni PHP tanpa dependensi untuk operasi masukan/keluaran nonblokir yang dibangun di sekitar satu perulangan peristiwa. Tidak memerlukan ekstensi — perangkat ini bekerja pada PHP bawaan menggunakan stream_select (atau ext-event/ext-ev jika tersedia). Dengan perangkat ini, Anda dapat menulis server yang berjalan lama, klien HTTP konkuren, dan jalur pengaliran data dalam PHP biasa.
Perulangan Global
ReactPHP modern (v1.2+) menyediakan perulangan bawaan melalui fasad statis React\EventLoop\Loop — Anda tidak perlu meneruskan instans perulangan ke setiap tempat. Jadwalkan panggilan balik dengan pengatur waktu; perulangan berjalan sampai tidak ada pekerjaan lagi.
<?php
require 'vendor/autoload.php';
use React\EventLoop\Loop;
Loop::addTimer(1.0, function () {
echo "fired after 1 second\n";
});
echo "scheduled\n";
// Loop::run() is auto-invoked at script shutdown in v1.2+Pengatur Waktu dan Pekerjaan Berkala
Pengaturan waktu nonblokir menggantikan sleep(). addTimer berjalan sekali; addPeriodicTimer berulang. Batalkan salah satunya untuk menghentikannya. Karena pengaturan ini digerakkan oleh perulangan, tugas lain tetap berjalan saat pengatur waktu menunggu.
<?php
use React\EventLoop\Loop;
$count = 0;
$timer = Loop::addPeriodicTimer(0.5, function () use (&$count, &$timer) {
echo 'tick ' . (++$count) . "\n";
if ($count === 4) {
Loop::cancelTimer($timer); // stop after 4 ticks
}
});Janji untuk Hasil Asinkron
ReactPHP mengembalikan janji untuk setiap operasi yang selesai nanti. Pasang then() untuk keberhasilan dan panggilan balik kedua untuk kegagalan. Janji dapat dikomposisikan, sehingga Anda dapat mengubah dan merangkai hasil tanpa membuat panggilan balik bersarang terlalu dalam.
<?php
use React\Promise\Promise;
function asyncDouble(int $n): Promise {
return new Promise(function ($resolve) use ($n) {
\React\EventLoop\Loop::addTimer(0.1, fn() => $resolve($n * 2));
});
}
asyncDouble(21)
->then(fn($r) => printf("result: %d\n", $r)) // 42
->catch(fn(\Throwable $e) => printf("err: %s\n", $e->getMessage()));HTTP Paralel dengan Klien Asinkron
Keuntungan utamanya: jalankan banyak permintaan HTTP secara konkuren dari satu utas. React\Http\Browser mengembalikan janji; React\Promise\all() menunggu seluruh kumpulan. Sepuluh permintaan berdurasi 1 detik selesai dalam sekitar 1 detik, bukan 10 detik.
<?php
use React\Http\Browser;
use function React\Promise\all;
$browser = new Browser();
$urls = [
'https://httpbin.org/delay/1',
'https://httpbin.org/delay/1',
'https://httpbin.org/delay/1',
];
$requests = array_map(fn($u) => $browser->get($u), $urls);
all($requests)->then(function (array $responses) {
echo 'all done: ' . count($responses) . " responses\n";
});Fiber Membuat Kode Terlihat Sinkron
Rantai panggilan balik dapat menjadi sulit dikelola. ReactPHP terintegrasi dengan react/async, yang menggunakan Fiber PHP 8.1 sehingga Anda dapat menjalankan await() pada sebuah janji dan menulis kode berurutan biasa. Pembungkus coroutine()/async() menjalankan fungsi Anda di dalam fiber.
<?php
use function React\Async\async;
use function React\Async\await;
use React\Http\Browser;
$main = async(function () {
$browser = new Browser();
$a = await($browser->get('https://httpbin.org/uuid'));
$b = await($browser->get('https://httpbin.org/uuid'));
echo (string) $a->getBody();
echo (string) $b->getBody();
});
$main();Server TCP Nonblokir
ReactPHP sangat unggul untuk server. SocketServer menerima koneksi dan memancarkan peristiwa; setiap koneksi sendiri merupakan aliran nonblokir. Satu proses dapat menangani ribuan klien secara bersamaan.
<?php
use React\Socket\SocketServer;
use React\Socket\ConnectionInterface;
$socket = new SocketServer('127.0.0.1:8080');
$socket->on('connection', function (ConnectionInterface $conn) {
$conn->write("Welcome\n");
$conn->on('data', function ($data) use ($conn) {
$conn->write('echo: ' . $data); // streamed back, non-blocking
});
});
echo "listening on 127.0.0.1:8080\n";Server HTTP dalam Beberapa Baris
Server react/http menangani permintaan dengan panggilan balik yang mengembalikan Response (atau janji yang menghasilkan nilai tersebut). Karena prosesnya persisten, Anda menyiapkan dependensi sekali — tetapi Anda juga bertanggung jawab atas pengelolaan memori di antara permintaan.
<?php
use React\Http\HttpServer;
use React\Http\Message\Response;
use Psr\Http\Message\ServerRequestInterface;
use React\Socket\SocketServer;
$http = new HttpServer(function (ServerRequestInterface $request) {
return Response::json(['path' => $request->getUri()->getPath()]);
});
$http->listen(new SocketServer('0.0.0.0:8000'));
echo "http://0.0.0.0:8000\n";Pengaliran Data Tanpa Penyanggaan
Aliran ReactPHP menerapkan tekanan balik: Anda dapat pipe() aliran yang dapat dibaca ke aliran yang dapat ditulis, dan runtime akan otomatis membatasi lajunya. Dengan demikian, Anda dapat menyalurkan gigabita dengan jejak memori kecil yang konstan, alih-alih memuat berkas ke dalam RAM.
<?php
use React\Stream\ReadableResourceStream;
use React\Stream\WritableResourceStream;
$source = new ReadableResourceStream(fopen('big.log', 'r'));
$dest = new WritableResourceStream(fopen('php://stdout', 'w'));
$source->pipe($dest); // back-pressure aware, never buffers whole fileDosa Besar: Memblokir Perulangan
Semuanya rusak saat Anda memanggil fungsi pemblokir di dalam pengendali — sleep(), PDO yang memblokir, curl_exec, atau file_get_contents pada URL. Fungsi-fungsi tersebut membekukan utas tunggal dan menghentikan setiap koneksi. Gunakan padanan React: Loop::addTimer untuk penundaan, clue/reactphp-* atau pengandar basis data asinkron untuk kueri, dan Browser untuk HTTP.
<?php
use React\EventLoop\Loop;
use function React\Async\await;
use React\Promise\Deferred;
// BAD: sleep(2); // freezes the entire loop
// GOOD: async delay that yields control
function delay(float $s): \React\Promise\PromiseInterface {
$d = new Deferred();
Loop::addTimer($s, fn() => $d->resolve(null));
return $d->promise();
}
// await(delay(2.0)); // inside a fiber/coroutineMembatasi Konkurensi
Percabangan tanpa batas dapat menghabiskan deskriptor berkas atau membebani API hilir. clue/mq-react milik ReactPHP mengantrekan pekerjaan dengan batas konkurensi, memproses N janji sekaligus sementara sisanya menunggu. Cara ini menerapkan tekanan balik pada beban keluar Anda sendiri.
<?php
use Clue\React\Mq\Queue;
use React\Http\Browser;
$browser = new Browser();
// At most 10 in-flight requests across 1000 URLs
$q = new Queue(10, null, fn($url) => $browser->get($url));
$promises = array_map(fn($u) => $q($u), $thousandUrls ?? []);
\React\Promise\all($promises)->then(function ($responses) {
echo 'completed ' . count($responses) . " with cap of 10\n";
});Pemeriksaan Singkat
Bagaimana cara menunggu selama 2 detik di dalam pengendali ReactPHP tanpa mengganggu konkurensi?
Ringkasan
ReactPHP menghadirkan I/O nonblokir ke PHP biasa:
- Satu loop peristiwa (fasad
Loop) mengendalikan pengatur waktu, soket, dan aliran — tidak memerlukan ekstensi. - Operasi mengembalikan janji;
all()menjalankan permintaan secara paralel, sedangkanreact/async+ Fiber memungkinkan Anda menggunakanawait()untuk menulis kode yang tampak sinkron. - Bangun peladen TCP/HTTP persisten dan aliran dengan tekanan balik yang menangani ribuan koneksi dalam setiap proses.
- Jangan pernah memblokir loop — gantikan
sleep/I/O pemblokir dengan pengatur waktu React dan penggerak asinkron.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Perulangan Peristiwa dengan ReactPHP” gratis?
Ya — teks lengkap “Perulangan Peristiwa dengan ReactPHP” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus PHP Academy, upgrade ke CoddyKit PRO. Kursus PHP Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Perulangan Peristiwa dengan ReactPHP”?
Jalankan I/O tanpa pemblokiran dengan perulangan peristiwa ReactPHP. Kamu berlatih PHP Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai PHP Academy?
Tidak diperlukan pengalaman sebelumnya. PHP Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Perulangan Peristiwa dengan ReactPHP” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran PHP Academy ini?
Ya. Setiap pelajaran PHP Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Model Konkurensi PHP
- Fiber PHP 8.1
- Perulangan Peristiwa dengan ReactPHP
- Server Berkinerja Tinggi dengan Swoole