本稿では、PHPを利用した非同期処理を実現する方法3選ということで、下記3つの方法を利用した実現方法をまとめていきます。
- pcntl_fork
- ReactPHP
- Swoole
非同期処理は、複数のタスクを同時に実行することで、パフォーマンスの向上や効率的なリソース利用が可能となります。
それぞれのメリットやデメリット、利用サンプルコードも含めてのご紹介となります。
pcntl_fork関数を使ったマルチプロセス
“pcntl_fork”関数を利用することで、親プロセスから子プロセスを生成し、並行してタスクを実現することができます。これにより、複数のプロセスを同時に実行し、非同期処理を実現します。
<?php
$pid = pcntl_fork();
if ($pid == -1) {
die('Fork failed');
} elseif ($pid) {
// 親プロセス
echo "Parent process, PID: " . posix_getpid() . PHP_EOL;
pcntl_wait($status);
} else {
// 子プロセス
echo "Child process, PID: " . posix_getpid() . PHP_EOL;
}
?>
Parent process, PID: 9095
Child process, PID: 9096
上記サンプルであh、pcntl_fork関数を使用してプロセスを分岐させています。
親プロセスは子プロセスのPIDを表示し、子プロセスの終了を待ちます。
メリット
- 同時に複数のタスクを実行できるため、処理速度が向上する
- プロセス間で独立したメモリ空間が確保されるため、お互いに影響を与えずに安全に並列処理が可能となる
デメリット
- マルチプロセスの管理が複雑であり、デバッグが他より困難である
- プロセス間通信が必要な場合、IPC (Inter-Process Communication)などの追加手段が必要
- リソースの消費が増加し、大量プロセスを生成するとシステム負荷が増える
ReactPHPを使ったイベントループ
ReactPHPは、イベントループを使って非同期処理を実現するPHPライブラリです。
イベントループは、タスクをキューに入れ、それらを非同期で実行する仕組みとなります。
まずは、Composerを使ってReactPHPをインストールします。下記コマンドをターミナルで実行することで利用可能となります。
% composer require react/event-loop react/socket react/stream
その後、PHPファイルを作成して書きのコードを入力します。
<?php
require 'vendor/autoload.php';
$loop = React\EventLoop\Factory::create();
$loop->addTimer(1, function () {
echo "Hello after 1 second!\n";
});
$loop->addTimer(2, function () {
echo "Hello after 2 seconds!\n";
});
$loop->run();
?>
Hello after 1 second!
Hello after 2 seconds!
メリット
- 非同期処理により、I/O待ちの間に他のタスクを処理することができるため、システム全体のパフォーマンスが向上する
- 対象のリクエストに対しても効率的に対応できるので、アプリケーションのスケーラビリティが向上する
- ReactPHPはオープンソースのため、活発なコミュニティが存在する
デメリット
- 非同期プロブラミングやイベント駆動の概念に慣れていない場合は、学習が必要
- 非同期コードのため、デバッグが難しい
- 一部の既存のPHPライブラリやフレームワークとの互換性が低い場合がある
Swooleを使った並行処理
wooleは、C/C++で書かれたPHP拡張モジュールで、高性能な非同期処理を実現できます。
Swooleを使うことで、コルーチンやイベントループ、マルチプロセスなどの機能を活用できます。
まず、SwooleはPHPの拡張機能であるので、Swoole自体は下記のようにインストールします。
% pecl install swoole
インストールが完了したら、php.iniに対して、「extension=swoole.so」を追記します。
設定が完了したら、下記のコードを入力して実行します。
<?php
$http = new Swoole\Http\Server('127.0.0.1', 9501);
$http->on('request', function ($request, $response) {
$response->end("<h1>Hello Swoole!</h1>");
});
$http->start();
?>
メリット
- 他の非同期処理と同様に複数の扶を並行して実行できるためシステムの拡張性が向上する
- コルーチンを利用して、簡潔なコードで非同期処理を実行できる
デメリット
- php.iniファイルに拡張情報を追加するので、導入ハードルが他と比べて高い
- レンタルサーバによっては利用できないケースが多い
- エラーハンドリングが複雑
最後に
今回は、PHPで非同期処理を実現する方法について、pcntl_fork関数、ReactPHP、Swooleの3つの方法を紹介しました。プロジェクトの要件に応じて、適切な方法を選択して非同期処理を実現しましょう。