+13

PHP == NodeJS ?

Chào mọi người, có lẽ mới đọc cái tiêu đề PHP == NodeJS mọi người nghĩ cú lừa chăng, và trả lời ngay là không thể có chuyện đó ngoại trừ việc cả PHP và nodeJS đều có thể code backend. Còn riêng việc xử lý bất đồng bộ (async) thì PHP tuổi gì so với NodeJS. Mình cũng đã nghĩ như thế, và các dự án PHP đã và đang làm cũng đều nghĩ ngay đến javascript để làm mấy việc realtime, bất đồng bộ, hay đa luồng này kia. Nhưng sự thực PHP và những thư viện hỗ trợ cho nó còn nhiều điều mạnh mẽ mà ta chưa biết, mạnh và kín tiếng khiến người ta quên nó là ai và nó đang ở đâu.

Hôm nay mình cùng các bạn chúng ta sẽ cùng tìm hiểu, đào bới lại xem sao. Mình cũng sẽ cố gắng viết vài bài, coi như vừa làm vừa tìm hiểu để xem tại sao người ta lại dùng ít vậy. Vậy là cái gì ?

Đây là chủ đề hôm nay mình muốn bàn tới và đang cố gắng tìm hiểu, thật ra mình đã biết đến nó vài năm trước qua một người bạn tuy nhiên chưa nhận ra điều đặc biệt nên cũng chưa bao giờ áp dụng trong dự án, cho đến khi đọc được một bài thấy mấy anh Mẽo nhận xét reactPHP = NodeJS thì mình mới ngớ ra trước giờ chúng ta phụ thuộc vào JS quá. Nào cùng xem nó có gì mà bọn USA lại nó vậy.

ReactPHP cơ bản chỉ là tập các thư viện PHP được dùng kết hợp với framework có sẵn hoặc php app để tạo ra một ứng dụng hoàn chỉnh, cốt lõi của nó là Event loop cung cấp các tiện ích, ví dụ như : Streams abstraction, xử lý DNS bất đồng bộ, network client/server, HTTP client/server và tương tác với các process.

Nghe đến khái niệm Event loop lại làm chúng ta nghĩ ngay ra JS. Nó là cơ chế giúp javascript thực hiện nhiều tác vụ cùng lúc, nó có tên gọi như vậy là vì có một vòng lặp vô hạn trong javascript runtime để lắng nghe các Events. ReactPHP cũng có nhé.

ReactPHP có gì ?

Core components

Event loop

Stream

Promise

Network Components

Socket

Datagram

Protocol Components

HTTP

HTTPClient

DNS

Utility Components

Cache

ChildProcess

PromiseStream

PromiseTimer

Trong khuôn khổ của bài viết hôm nay mình sẽ tập trung giới thiệu về Event loopTimer trong phần core component nhé.

Trước khi bắt đầu chúng ta cần lưu ý rằng, bất đồng bộ không có nghĩa là song song chỉ là chúng ta không xử lý php theo kiểu blocking như trước mà là non-blocking.

Event loop

Event loop là thành phần cốt lõi của reactPHP, implement từ Reator pattern, nó là thành phần cấp thấp nhất và mọi thành phần khác đều phải sử dụng nó. Event loop chạy trên một thread và chịu trách nhiệm lập lịch cho những xử lý bất đồng bộ.

Để sử dụng event loop khá đơn giản

composer require react/event-loop:^1.1.0

Tiếp theo là khởi tạo một loop

<?php
$loop = React\EventLoop\Factory::create();

// Code sử dụng $loop

$loop->run();

Trong đoạn code trên chúng ta sử dụng implementations Factory để khởi tạo một loop. Trong factory đơn giản là lựa chọn những tiện ích có sẵn và chọn ra cái phù hợp với loop của chúng ta.

Ví dụ một chút về khả năng xử lý interval với event loop chúng ta tạo file test.php

<?php

require __DIR__ . '/../vendor/autoload.php';

$loop = React\EventLoop\Factory::create();

$loop->addTimer(0.8, function () {
    echo 'world!' . PHP_EOL;
});

$loop->addTimer(0.3, function () {
    echo 'hello ';
});

$loop->run();

Chạy file trên khá đơn giản chỉ cần

php test.php

output

hello world!

Chúng ta có thể thấy hàm addTimer cho phép định nghĩa thời gian khi nào thì chạy lệnh nào, nên ở đây hello sẽ được chạy trước vì thời gian set delay là 0.3s còn world! sẽ chạy sau vì delay 0.8s.

Timer

Timer có thể xử lý code trước hoặc sau một khoảng thời gian, tương tự interval và timeout trong javascript.

Như theo ví dụ trên thì chúng ta có thể set thời gian thực thi cho một đoạn code nào đó, xác định thành phần nào cần chạy trước và thành phần nào cần chạy sau.

Ngoài ra chúng ta có thể set cho đoạn code chạy đến khi nào thì dừng lại, giống như break trong vòng lặp vậy.

<?php

require __DIR__ . '/../../../../vendor/autoload.php';

$loop = React\EventLoop\Factory::create();
$count = 0;

$timer = $loop->addPeriodicTimer(0.1, function () use (&$count) {
    echo ++$count. PHP_EOL;
});

$loop->addTimer(1.0, function () use ($loop, $timer) {
    $loop->cancelTimer($timer);
    echo 'OK Done' . PHP_EOL;
});

$loop->run();

và kế quả

1 2 3 4 5 6 7 8 9 OK Done

Ở đây chúng ta sử dụng addPeriodicTimer để lặp đi lặp lại 0.1s một lần việc in ra biến $count sau khi đã tăng lên 1 đơn vị. sau đó trong function addTimer được chạy vào thời điểm delay 1s, tại đây có gọi function cancelTimer sẽ có nhiệm vụ dừng việc đếm bên trên lại và in ra OK Done.

Cả 2 ví dụ trên chúng ta đều thực thi loop đơn giản với việc gọi function

$loop->run();

Để dừng một loop lại chúng ta có thể gọi :

$loop->stop();

Kết luận

Trên đây là một vài giới thiệu của mình về thư viện reactPHP và một số tác dụng của nó, chỉ là một phần nhỏ trong những thứ mà reactPHP có thể làm được, trong bài viết sau mình sẽ cố gắng đi sau vào nhiều ví dụ cụ thể hơn để làm rõ liệu PHP có thực sự so sánh với NodeJS trong việc xử lý bất đồng bộ được hay không. Hy vọng reactPHP sẽ không làm mình và các bạn thất vọng!

Tham khảo

https://reactphp.org/event-loop/

https://medium.com/@kornatzky/reactphp-is-node-js-in-php-82830c71004e


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí