【PHP8.x】pclose関数の使い方

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

作成日: 更新日:

基本的な使い方

『pclose関数は、popen関数によって開かれたプロセスパイプを閉じる処理を実行する関数です。』 PHPスクリプトからpopen関数を使って外部コマンドを実行した際に、そのコマンドとの通信路(パイプ)が確立されますが、pclose関数はその通信を安全に終了させる役割を担います。この関数を呼び出すと、実行中のコマンドプロセスが完了するのを待ち、その後に関連付けられたファイルポインタを閉じます。これにより、システムリソースが適切に解放され、ゾンビプロセスが発生するのを防ぎます。引数には、popen関数が返した有効なファイルポインタ(リソース型の値)を一つ指定します。処理が成功すると、実行したコマンドの終了ステータスコードを整数値で返します。一般的に、コマンドが正常に完了した場合は0が返され、何らかのエラーが発生した場合は0以外の数値が返ります。この戻り値を利用することで、外部コマンドの実行が成功したか失敗したかを判定できます。引数が無効なリソースであるなど、関数自体の実行に失敗した場合はfalseを返します。したがって、popen関数を使用した際には、処理の最後に必ずpclose関数を対で呼び出すことが推奨されます。

構文(syntax)

1<?php
2
3/* popen() が返すファイルポインタ (リソース) */
4$handle = popen('/usr/bin/some_command', 'r');
5
6/*
7 * プロセスパイプを閉じ、実行したコマンドの終了ステータスを返す
8 * 構文: pclose(resource $handle): int|false
9 */
10$exit_status = pclose($handle);
11
12?>

引数(parameters)

resource $handle

  • resource $handle: popen()関数などで開かれたプロセスとの通信用のリソースを指定

戻り値(return)

int|false

pclose 関数は、popen() 関数で開かれたプロセスを閉じ、その終了ステータスを返します。正常に閉じられた場合はプロセスの終了コード(通常は0)、エラーが発生した場合は false を返します。

サンプルコード

PHPでpopenとpcloseを使う

1<?php
2
3/**
4 * このスクリプトは、pclose() 関数を使用して外部プロセスとのパイプを閉じる方法を示します。
5 * popen() で開かれたパイプを閉じます。
6 */
7
8/**
9 * 外部コマンドを実行し、その出力を取得してパイプを閉じる例。
10 */
11function demonstratePclose(): void
12{
13    // 実行するコマンドを定義します。
14    // Windows の場合は 'dir' または 'where' など、
15    // Linux/macOS の場合は 'ls' または 'which' などを使用できます。
16    $command = (PHP_OS_FAMILY === 'Windows') ? 'dir' : 'ls -la';
17    echo "外部コマンドを実行します: {$command}\n";
18
19    // popen() を使って外部コマンドを実行し、その出力ストリームへのパイプを開きます。
20    // 'r' モードは、コマンドの標準出力から読み込むことを意味します。
21    $handle = popen($command, 'r');
22
23    if ($handle === false) {
24        echo "エラー: コマンド '{$command}' を実行できませんでした。\n";
25        return;
26    }
27
28    echo "パイプを開きました。出力を読み込み中...\n";
29
30    // パイプからすべての出力を読み込みます。
31    $output = '';
32    while (!feof($handle)) {
33        $output .= fread($handle, 8192); // 8KB ずつ読み込む
34    }
35
36    echo "\n--- 外部コマンドの出力 ---\n";
37    echo $output;
38    echo "--- 出力終了 ---\n\n";
39
40    // pclose() を使ってパイプを閉じます。
41    // 戻り値はコマンドの終了ステータス(int)または失敗した場合は false です。
42    $returnStatus = pclose($handle);
43
44    if ($returnStatus === false) {
45        echo "エラー: パイプを閉じるのに失敗しました。\n";
46    } else {
47        echo "パイプを閉じました。コマンドの終了ステータス: {$returnStatus}\n";
48        if ($returnStatus !== 0) {
49            echo "注記: コマンドはゼロ以外の終了ステータスで終了しました(通常はエラーを示します)。\n";
50        }
51    }
52}
53
54// 関数の実行
55demonstratePclose();
56
57?>

PHPのpclose()関数は、popen()関数によって開かれた外部プロセスとの通信パイプを閉じるために使用されます。popen()は、PHPスクリプトから外部のコマンドを実行し、そのコマンドの標準入出力に対して「パイプ」という接続を開き、データを読み書きできるようにする機能です。

サンプルコードでは、最初にpopen()を用いて外部コマンド(例: Windowsのdir、Linux/macOSのls -la)を実行し、そのコマンドの出力ストリームを読み込むためのパイプを開いています。popen()は、このパイプへのアクセスに使うリソースを返します。

パイプから外部コマンドの出力を全て読み込んだ後、pclose()関数が呼び出されます。この関数の引数 $handle には、popen()で取得したパイプのリソースを渡します。pclose()はパイプを閉じるとともに、実行された外部コマンドの終了ステータスを整数値として返します。通常、0はコマンドの正常終了を示し、それ以外の値はエラーを示唆します。もしパイプを閉じる操作自体に失敗した場合は、戻り値としてfalseが返されます。

外部プロセスとの連携において、pclose()を使ってパイプを確実に閉じることは、システムリソースを適切に解放し、プログラムの安定性を保つ上で非常に重要です。

pclose()は、popen()で開いた外部プロセスとのパイプを必ず閉じるために使用します。パイプを開きっぱなしにすると、システムリソースを消費し続ける(リソースリーク)原因となるため、処理が終わったら確実に閉じてください。

popen()と同様に、pclose()も失敗する可能性があります。戻り値がfalseでないかを必ず確認し、適切なエラー処理を記述することが重要です。

pclose()の戻り値は外部コマンドの終了ステータスです。0以外の値は、通常、コマンドが何らかのエラーで終了したことを示します。このステータスも適切にチェックし、エラー発生時に対応できるように準備しておくことが、安全で堅牢なコードの利用に繋がります。OSによって実行する外部コマンドが異なる点にも注意してください。

関連コンテンツ

【PHP8.x】pclose関数の使い方 | いっしー@Webエンジニア