Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】passthru()関数の使い方

passthru関数の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

passthru関数は、外部プログラムを実行し、その出力を直接ブラウザに出力する関数です。PHPスクリプトからシェルコマンドなどの外部コマンドを実行する必要がある場合に利用されます。

この関数は、コマンドを引数として受け取り、そのコマンドをOSのシェルを通して実行します。実行されたコマンドの標準出力は、バイナリデータを含めて、そのままクライアントのブラウザに送信されます。passthru関数は、コマンドの実行結果を文字列として返すのではなく、直接出力ストリームに書き込む点がexec関数やsystem関数と異なります。

passthru関数は、主に外部プログラムが生成する生の出力データを、PHPスクリプトを介してクライアントに配信する場合に便利です。例えば、画像処理プログラムや動画エンコーダなどの出力を直接ブラウザに表示する場合などが考えられます。

セキュリティ上の注意点として、passthru関数に渡すコマンドは、慎重に扱う必要があります。ユーザーからの入力に基づいてコマンドを組み立てる場合、コマンドインジェクション攻撃のリスクが高まります。入力値の検証やエスケープ処理を徹底し、安全なコマンド実行を心がける必要があります。

また、safe_modeが有効な場合、passthru関数の利用は制限されることがあります。disable_functionsディレクティブでpassthru関数が無効化されている場合もあります。これらの設定を確認し、利用環境に合わせて適切に対応する必要があります。

構文(syntax)

1passthru ( string $command , int &$return_var = null ) : void

引数(parameters)

string $command, ?int &$result_code = null

  • string $command: 実行するコマンドを指定する文字列
  • ?int &$result_code: コマンドの終了コードを受け取るための変数への参照。指定しない場合はNULLになる

戻り値(return)

void

passthru関数は、外部コマンドの実行結果を標準出力に直接出力し、コマンドの終了ステータスを返しますが、PHPの関数としては直接的な戻り値はありません。

サンプルコード

PHP passthru でファイル操作を行う

1<?php
2
3/**
4 * passthru関数を使用してファイルを作成し、その内容を表示、そして削除するデモンストレーションを行います。
5 * 外部コマンドの生の出力を直接PHPの出力バッファに流し込み、コマンドの終了ステータスを取得します。
6 *
7 * 注意: このコードはLinux/macOS環境のコマンドを想定しています。
8 * Windows環境で実行する場合、echo, cat, rmコマンドをdel, typeなどに適宜変更する必要があります。
9 */
10function demonstrate_passthru_with_file_operations(): void
11{
12    // 一時ファイル名を生成
13    $tempFile = 'temp_passthru_test_file.txt';
14    $fileContent = "Hello from PHP passthru!\nThis is a test file content.";
15
16    echo "--- Creating file: '{$tempFile}' ---\n";
17    // echo コマンドでファイルを作成し内容を書き込む
18    // escapeshellarg() で引数を適切にエスケープし、コマンドインジェクションを防ぎます。
19    $commandCreate = "echo " . escapeshellarg($fileContent) . " > " . escapeshellarg($tempFile);
20    passthru($commandCreate, $resultCodeCreate);
21    echo "Command: '{$commandCreate}' executed. Result code: {$resultCodeCreate}\n";
22    if ($resultCodeCreate === 0) {
23        echo "File created successfully.\n\n";
24
25        echo "--- Displaying file content: '{$tempFile}' ---\n";
26        // cat コマンドでファイルの内容を表示
27        // passthruは外部コマンドの出力を直接ブラウザに出力します。
28        $commandCat = "cat " . escapeshellarg($tempFile);
29        passthru($commandCat, $resultCodeCat);
30        echo "\nCommand: '{$commandCat}' executed. Result code: {$resultCodeCat}\n";
31        if ($resultCodeCat === 0) {
32            echo "File content displayed successfully.\n\n";
33        } else {
34            echo "Failed to display file content.\n\n";
35        }
36
37        echo "--- Deleting file: '{$tempFile}' ---\n";
38        // rm コマンドでファイルを削除
39        $commandDelete = "rm " . escapeshellarg($tempFile);
40        passthru($commandDelete, $resultCodeDelete);
41        echo "Command: '{$commandDelete}' executed. Result code: {$resultCodeDelete}\n";
42        if ($resultCodeDelete === 0) {
43            echo "File deleted successfully.\n\n";
44        } else {
45            echo "Failed to delete file.\n\n";
46        }
47    } else {
48        echo "Failed to create file. Please check permissions or command syntax.\n\n";
49    }
50}
51
52// 関数を実行して、passthruの動作を確認
53demonstrate_passthru_with_file_operations();

passthru関数は、PHPから外部のシェルコマンドを実行し、そのコマンドが標準出力に書き出す内容を、PHPの出力バッファへ直接流し込む機能を提供します。これにより、コマンドの生の出力をそのままWebブラウザなどに表示できます。

最初の引数$commandには、実行したいシェルコマンドを文字列で指定します。セキュリティ上の理由から、ユーザー入力など外部からの値を含めるコマンド引数は、escapeshellarg()関数で適切にエスケープすることが非常に重要です。オプションの第二引数&$result_codeは参照渡しで、実行したコマンドの終了ステータス(成功なら通常0)を受け取る整数型の変数です。この値を確認することで、コマンドが正常に終了したかどうかの判断ができます。passthru関数自体の戻り値はvoidであり、PHP側には何も値を返しません。

サンプルコードでは、このpassthru関数を用いて、一時ファイルを操作する一連のデモンストレーションを行っています。具体的には、まずechoコマンドを使って指定した内容を持つ一時ファイルを「作成」し、次にcatコマンドでそのファイルの内容を「表示」します。passthruの特性により、catコマンドの出力が直接PHPの出力として表示されます。最後にrmコマンドで一時ファイルを「削除」しています。それぞれのコマンド実行後には$result_codeを確認し、コマンドが正常に実行されたかを判断しています。このコードはLinux/macOS環境のコマンドを前提としており、Windows環境で実行する場合は、echo, cat, rmコマンドを適宜変更する必要があります。

passthru関数は、外部コマンドの生出力を直接Webサーバーの出力バッファに流すため、デバッグ情報の表示やストリーミング処理に適しています。サンプルコードのように、ユーザーからの入力値をコマンドに渡す際は、必ずescapeshellarg()escapeshellcmd()関数で適切にエスケープし、コマンドインジェクションを防ぐことが極めて重要です。OSによって利用できるコマンド名が異なる点にも注意が必要です。また、第2引数のresult_codeでコマンドの終了ステータスを確認し、処理の成否を判断する習慣をつけましょう。ファイル操作時には、PHPが動作するユーザーのファイルアクセス権限も適切に設定する必要があります。

PHP passthruでコマンド実行と終了コード取得

1<?php
2
3/**
4 * PHPのpassthru関数を使用してシェルコマンドを実行し、
5 * その結果を直接出力するサンプルコードです。
6 * コマンドの終了コードも取得し、動作の成否を確認します。
7 *
8 * キーワード「php passthru not working」に対応するため、
9 * 成功例と失敗例を示し、終了コードの確認方法を重点的に説明します。
10 * passthruはコマンドの出力を直接標準出力に送り、PHPのスクリプトでは捕捉されません。
11 * 終了コードを取得することで、コマンドが成功したか失敗したかを判断できます。
12 */
13
14/**
15 * 指定されたシェルコマンドを実行し、その出力を直接表示します。
16 * コマンドの終了コードも取得し、結果の成否を報告します。
17 *
18 * @param string $command 実行するシェルコマンド。
19 * @return void
20 */
21function executeShellCommandWithPassthru(string $command): void
22{
23    echo "--- 実行コマンド: \"{$command}\" ---\n";
24
25    // コマンドの終了コードを格納する変数(参照渡し)
26    $resultCode = null;
27
28    // passthruはコマンドの出力を直接ウェブサーバーの出力バッファに送るため、
29    // 戻り値はvoidです。成功・失敗は$resultCodeで判断します。
30    passthru($command, $resultCode);
31
32    echo "終了コード: " . var_export($resultCode, true) . "\n";
33
34    if ($resultCode === 0) {
35        echo "ステータス: 成功\n";
36    } else {
37        echo "ステータス: 失敗 (コマンドが見つからない、またはエラーが発生しました)\n";
38        echo "ヒント: 'not working' の原因は、コマンドが見つからない、権限がない、\n";
39        echo "        またはコマンド自体がエラーを返したことかもしれません。\n";
40    }
41    echo "--------------------------------------------------\n\n";
42}
43
44// --------------------------------------------------
45// サンプル実行
46// --------------------------------------------------
47
48// 1. 正常に動作するコマンドの例
49// OSによって異なるコマンドを使用します (Linux/macOS: 'ls -la', Windows: 'dir')
50if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
51    executeShellCommandWithPassthru('dir');
52    executeShellCommandWithPassthru('echo PHP passthru on Windows works!');
53} else {
54    executeShellCommandWithPassthru('ls -la');
55    executeShellCommandWithPassthru('echo PHP passthru on Linux/macOS works!');
56}
57
58// 2. 存在しないコマンドの例
59// ほとんどのシステムでこのコマンドは存在しないため、失敗するはずです。
60// この場合、終了コードは0以外になります。
61executeShellCommandWithPassthru('non_existent_command_php_test_123');
62
63// 3. エラーを返すコマンドの例
64// (存在するコマンドだが、不正なオプションによりエラーとなる場合)
65// この場合も、終了コードは0以外になります。
66if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
67    executeShellCommandWithPassthru('dir /invalid_option'); // Windowsのdirコマンドでの不正なオプション
68} else {
69    executeShellCommandWithPassthru('ls --invalid-option'); // Linux/macOSのlsコマンドでの不正なオプション
70}
71
72// 4. 標準エラー出力も直接出力されることを示す例
73// (ファイルが存在しない場合のcatコマンドなど)
74// 通常、エラーメッセージも直接出力され、終了コードは0以外になります。
75if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { // Windowsのtypeコマンドはエラーコードが0の場合があるのでLinux/macOS向け
76    executeShellCommandWithPassthru('cat non_existent_file_for_passthru_test.txt');
77}
78
79?>

PHPのpassthru関数は、指定されたシェルコマンドを実行し、そのコマンドの出力をPHPスクリプトを介さずに、直接Webサーバーの標準出力に送信する機能を提供します。これにより、コマンド実行のリアルタイムな進捗や結果をユーザーに表示できます。

最初の引数$commandには、実行したいシェルコマンドを文字列で指定します。2番目のオプション引数&$result_codeは参照渡しで、コマンドの終了コードを格納するために使用されます。この終了コードは、コマンドが正常に完了した場合は通常0、何らかのエラーが発生した場合は0以外の整数値となります。

passthru関数の戻り値はvoidであり、コマンドの出力自体をPHPスクリプト内で捕捉することはできません。そのため、コマンドの成功・失敗を判断するには、この$result_codeの値を検査することが非常に重要です。

サンプルコードでは、ls -ladirのような正常に動作するコマンドを実行した場合と、存在しないコマンドや不正なオプションを含むコマンドを実行した場合の両方を示しています。正常なコマンドでは$result_code0となり「成功」と判断されますが、失敗するコマンドでは0以外の値が返され「失敗」と判断されます。このように$result_codeを確認することで、「php passthru not working」という状況に直面した際に、コマンドが見つからない、実行権限がない、またはコマンド自体がエラーを発生させているといった具体的な原因を特定する上で役立ちます。

passthru関数は、実行したコマンドの出力をPHPスクリプトで受け取れず、直接ウェブページ等へ出力します。そのため、コマンドの成否は第2引数で取得する終了コード(0が成功、それ以外が失敗)で必ず確認してください。これが「動かない」と感じる原因の特定に役立ちます。外部からの入力をコマンド引数に直接渡すと、OSコマンドインジェクションというセキュリティリスクが発生するため、必ず厳しく検証・エスケープしてください。また、実行コマンドはOS環境に依存し、PHPが動作するユーザーの権限で実行される点にも注意が必要です。

php passthruでstderrを取得する

1<?php
2
3/**
4 * passthru 関数を使用して外部コマンドを実行し、その出力を直接表示するサンプル。
5 *
6 * この例では、標準エラー出力 (stderr) を標準出力 (stdout) にリダイレクトすることで、
7 * passthru がエラーメッセージもキャプチャして表示する方法を示します。
8 * また、コマンドの終了コードを取得する方法も示します。
9 */
10
11// コマンドの終了コードを格納する変数
12$commandResultCode = null;
13
14// 実行する外部コマンドを定義します。
15// `bash -c "..."` を使用して、標準出力と標準エラー出力の両方にメッセージを出力し、
16// 意図的に終了コード1で終了するコマンドを作成します。
17// `2>&1` は、標準エラー出力 (ファイルディスクリプタ2) を標準出力 (ファイルディスクリプタ1) に
18// リダイレクトするシェル構文です。これにより、passthru が標準エラー出力もPHPの出力に流します。
19$command = 'bash -c "echo \'--- 標準出力からのメッセージです ---\'; >&2 echo \'--- 標準エラー出力からのメッセージです ---\'; exit 1" 2>&1';
20
21echo "--- 外部コマンドの実行を開始します ---\n";
22echo "実行コマンド: '{$command}'\n\n";
23
24// passthru 関数を実行し、外部コマンドの出力を直接PHPの出力バッファに流します。
25// 第二引数に渡した変数に、コマンドの終了コードが格納されます。
26passthru($command, $commandResultCode);
27
28echo "\n--- 外部コマンドの実行が終了しました ---\n";
29
30// 取得したコマンドの終了コードを表示します。
31echo "コマンドの終了コード: {$commandResultCode}\n";
32
33// 終了コードに基づいてメッセージを表示します。
34if ($commandResultCode !== 0) {
35    echo "注意: コマンドは正常に終了しませんでした。上記出力にエラー情報が含まれている可能性があります。\n";
36} else {
37    echo "コマンドは正常に終了しました。\n";
38}
39
40?>

PHPのpassthru関数は、指定した外部コマンドを実行し、その結果をPHPの出力バッファへ直接出力する機能を提供します。これは、外部コマンドの実行結果をリアルタイムでユーザーに表示したい場合などに特に役立ちます。

このサンプルコードでは、passthru関数を使って外部のシェルコマンドを実行しています。注目すべきは、コマンド文字列に2>&1というシェル構文が含まれている点です。これは、外部コマンドが生成する標準エラー出力 (stderr) を標準出力 (stdout) にリダイレクトする指示です。これにより、エラーメッセージのような標準エラー出力の内容もpassthruを通じて直接表示されることを示しています。

passthru関数の第一引数には、実行したいコマンドを文字列で渡します。第二引数はオプションで、コマンドの終了コードを格納するint型の変数を参照渡しで指定できます。コマンドが正常に終了した場合は通常0が、エラーが発生した場合は0以外の値がこの変数に設定されます。

この関数は、コマンドの出力をPHPの内部変数として受け取るのではなく、直接出力バッファへ流すため、戻り値はvoid(何も返さない)となっています。したがって、コマンドの具体的な出力内容をPHPスクリプト内で処理したい場合には適しませんが、外部コマンドの進捗状況などをユーザーにそのまま見せたい場合に非常に有効です。サンプルでは、取得した終了コードに基づいて、コマンドの成否を判断し、メッセージを表示しています。

passthru関数は外部コマンドの出力を直接PHPの出力バッファへ流すため、出力をPHP側で加工したり取得したりしたい場合には適していません。コマンドの成否は、関数の戻り値ではなく、第二引数で受け取る終了コードで必ず確認してください。0以外のコードは通常エラーを示します。また、標準エラー出力(stderr)はデフォルトではPHPの出力には含まれないため、サンプルコードのように2>&1などでリダイレクトしない限り表示されません。最も重要な点として、実行するコマンド引数にユーザーからの入力値を直接利用すると、コマンドインジェクションと呼ばれる深刻なセキュリティ脆弱性の原因となります。そのため、必ずescapeshellarg()escapeshellcmd()などの関数で適切にエスケープ処理を施してください。実行するコマンドはサーバーの環境に依存するため、異なる環境での動作確認も重要です。

PHP: passthru と shell_exec の違いを理解する

1<?php
2
3/**
4 * passthru() と shell_exec() の主な違いを示すサンプルコードです。
5 *
6 * passthru():
7 * - コマンドの出力を直接標準出力(ブラウザやコンソール)に流します。
8 * - 戻り値は void です。
9 * - 第2引数でコマンドの終了ステータス(エラーコード)を取得できます。
10 *
11 * shell_exec():
12 * - コマンドの出力を文字列として返し、プログラム内でその文字列を操作できます。
13 * - 戻り値はコマンドの出力文字列です。
14 * - コマンドの終了ステータスを直接取得することはできません。
15 */
16function demonstratePassthruVsShellExec(): void
17{
18    echo "--- passthru() の使用例 ---" . PHP_EOL;
19    $commandPassthru = "echo 'Hello from passthru! The current directory is:' && ls -ld .";
20    $resultCodePassthru = null; // PHP 8 の ?int 型に合わせ、null で初期化可能
21
22    echo "passthru() でコマンドを実行中: '$commandPassthru'" . PHP_EOL;
23    // passthru() はコマンドの出力を直接出力します。
24    // 第2引数 $resultCodePassthru にコマンドの終了コードが設定されます。
25    passthru($commandPassthru, $resultCodePassthru);
26    echo "passthru() 実行後の終了コード: " . ($resultCodePassthru ?? '取得できませんでした') . PHP_EOL;
27
28    echo PHP_EOL . "--- shell_exec() の使用例 ---" . PHP_EOL;
29    $commandShellExec = "echo 'Hello from shell_exec! The current date is:' && date";
30
31    echo "shell_exec() でコマンドを実行中: '$commandShellExec'" . PHP_EOL;
32    // shell_exec() はコマンドの出力を文字列として返します。
33    // 出力を表示するには、別途 echo などが必要です。
34    $outputShellExec = shell_exec($commandShellExec);
35
36    echo "shell_exec() が返した出力:\n";
37    echo $outputShellExec ?? "[出力なし]" . PHP_EOL;
38    // shell_exec() はコマンドの終了コードを直接取得できません。
39    // 終了コードが必要な場合は、`exec()` や `system()` 関数を使用するか、
40    // コマンド自身が出力を介して終了コードを伝えるように設計する必要があります。
41
42    echo PHP_EOL . "--- 結論 ---" . PHP_EOL;
43    echo "passthru() は出力を直接表示し、終了コードも取得できるため、" . PHP_EOL;
44    echo "大きなファイルを処理したり、リアルタイムの出力を必要とする場合に適しています。" . PHP_EOL;
45    echo "shell_exec() は出力を文字列として取得し、プログラムで加工できるため、" . PHP_EOL;
46    echo "コマンドの出力をPHPスクリプト内で利用・解析する場合に適しています。" . PHP_EOL;
47}
48
49// 関数を実行して、passthru() と shell_exec() の動作を確認します。
50demonstratePassthruVsShellExec();
51
52?>

PHP 8で利用できるpassthru関数は、外部のコマンドを実行し、その出力を直接標準出力(ウェブページやコンソールなど)に流すための機能です。引数として、実行したいコマンドを文字列$commandで指定します。オプションの引数&$result_codeには、コマンドの実行が成功したか、またはエラーで終了したかを示す数値(終了ステータス)が格納されます。この関数の戻り値はvoidであり、関数自体は何も返しません。

この関数は、コマンドの実行結果をリアルタイムで表示したい場合や、PHPスクリプトが大きな出力を直接ユーザーに見せたい場合に特に適しています。例えば、lsコマンドでファイル一覧を表示したり、catコマンドでファイルの内容を表示したりする際に、その結果をそのままブラウザやターミナルに表示できます。

サンプルコードでは、passthruecholsコマンドの出力を直接表示し、その終了コードも$resultCodePassthru変数に格納していることがわかります。

これに対し、shell_exec関数も外部コマンドを実行しますが、その出力は文字列としてPHPスクリプトに返されます。そのため、shell_execはコマンドの出力をPHPプログラム内で加工したり、変数に格納して利用したい場合に適しています。しかし、shell_execではコマンドの終了ステータスを直接取得することはできません。

結論として、出力を直接表示し、かつ終了ステータスも取得したい場合はpassthruを、出力をPHPスクリプトで細かく制御したい場合はshell_execを選択すると良いでしょう。

これらの関数は外部コマンドを実行するため、ユーザーからの入力を直接コマンドに含める場合、OSコマンドインジェクションの危険性があります。必ずescapeshellarg()escapeshellcmd()で適切にエスケープ処理を行ってください。

passthru()はコマンドの出力を直接標準出力へ流し、終了コードも取得できます。リアルタイム表示や大容量出力に適しますが、PHPスクリプト内で出力内容を加工することはできません。

一方、shell_exec()はコマンドの出力を文字列として取得し、PHP内で柔軟に加工できます。しかし、大量の出力はメモリを消費する可能性があり、コマンドの終了コードを直接取得することはできません。

どちらの関数も、コマンドが意図通りに実行されたかを確認するため、戻り値や終了コードを用いた適切なエラーチェックが不可欠です。

関連コンテンツ

関連プログラミング言語