Symfony Component Advent Calendar 2023の1日目の記事です。
PHP内でコマンドを実行 "Process"
Processは、PHP内でサブプロセスとしてコマンドを実行します。PHPでは、exec
などでコマンド実行できますが、このコンポーネントはOSにより異なる引数のエスケープ処理を行ってくれます。Symfony以外でも使えます。
インストール
composer require symfony/process
サブプロセス実行
指定のコマンドでProcess
オブジェクトを作って、 run()
を呼び出すことで実行できます。
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
$process = new Process(['docker', 'compose' , 'up', '-d']);
$process->run();
if ($process->isSuccessful() === false) {
throw new ProcessFailedException($process);
}
echo $process->getOutput();
環境変数
サブプロセスに環境変数を渡すことも可能です。
$process = new Process(['env'], env: ['TEST_ENV' => 'test_value']);
$process->run();
echo $process->getOutput(); // 環境変数のリストに TEST_ENV=test_valueが追加されてる
非同期処理
サブプロセスを非同期処理で実行することも可能です。また、途中でプロセスを待機状態にもできます。wait()
メソッドもありますが、個人的にはwaitUntil()
がおすすめです。
$first = new Process(['date']);
$first->start();
while ($process->isRunnning()) {
// 実行中の間ループ
echo '..';
}
echo $first->getOutput(); // 2023-12-01 10:00:00
$second = new Process(['date']);
$second->start();
$second->waitUntil(function ($type, $output): bool { // callbackがtrueを返すまで待機
$third = new Process(['sleep', '10']); // 10秒スリープ
$third->run();
return true;
});
echo $third->getOutput(); // 2023-12-01 10:00:10
まとめ
今回はProcess
をご紹介しました。うっかりexec()
使うよりも安全にコマンド実行できますし、非同期処理もうまく使えばとても便利です。