関数・クラス解説

proc_open

version:PHP 4 >= 4.3.0, PHP 5, PHP 7 (公式)

コマンドを実行し、入出力用にファイルポインタを開く

公式リファレンス

書式

proc_open ( mixed $cmd , array $descriptorspec , array &$pipes [, string $cwd [, array $env [, array $other_options ]]] ) : resource

説明

proc_open() は popen() と よく似ていますが、プログラムの実行をさらに細かく制御できる点で違います。

パラメータ

cmd
実行するコマンドラインを string として渡します。 特殊な文字は適切にエスケープされ、適切にクォートされます。
注意: Windows では、 other_options の bypass_shell を TRUE に設定しないと、 cmd.exe (実際は%ComSpec%) に cmd の値を クォートしないまま (つまり、proc_open() に渡されたそのままの値を) /c と一緒に渡してしまいます。 この振る舞いによって、cmd.exe が cmd からクォートを削除してしまうため、 (詳細は cmd.exe のドキュメントを参照してください) 予期しない、潜在的に危険とさえ言える結果になります。なぜなら、 cmd.exe のエラーメッセージには、 渡された cmd (の一部) が含まれる可能性があるからです(下の例を見てください)。
PHP 7.4.0 以降、cmd にはコマンドの引数も含めた array を渡せるようになりました。 この場合、プロセスは直接(シェルを介さずに)オープンされ、PHP が必要な引数のエスケープを全て行います。
注意: Windows では、array で渡されるコマンドライン引数のエスケープは、 コマンドライン引数の解釈が VCランタイムによって行われるものと互換性があることを前提にして行われます。
descriptorspec
数値添字の配列で、ディスクリプタ番号をキーとし、PHP がその ディスクリプタをどのように子プロセスに渡すかを表すのが 対応する値となります。 0 が標準入力 (stdin)、1 が標準出力 (stdout) で、 2 が標準エラー出力 (stderr) となります。 各要素は、次のようになります。
  • プロセスに渡すパイプをあらわす配列。 最初の要素はディスクリプタの型で、2 番目の要素がその型に対応するオプションとなります。 使用できる型は pipe (2 番目の要素は、 プロセスにパイプの読み込み側を渡すのなら r、 書き込み側を渡すのなら w) および file (2 番目の要素はファイル名) です。
  • 実際のファイルディスクリプタ (オープンしたファイルやソケット、 STDIN など) をあらわすストリームリソース。
ファイルディスクリプタの番号は、特に 0, 1, 2 に限られているわけでは ありません。有効であるどのようなファイルディスクリプタの番号も指定でき、 それは子プロセスに渡されます。これにより、あるスクリプトと、 子プロセスとして起動している別のスクリプトとの間で通信ができます。 特に、これは PGP や GPG、openssl といったプログラムにパスフレーズを より安全な方法で渡したいとき威力を発揮します。 補助的なファイルディスクリプタを介して、そのようなプログラムの 状態を取得するのにも便利です。
pipes
PHP 側で生成されたパイプの終端にあたる ファイルポインタの配列。
cwd
コマンドの初期作業ディレクトリ。 完全パスである必要があります。 デフォルト値 (現在の PHP プロセスの作業ディレクトリ) を使用したい場合は NULL を指定します。
env
実行するコマンドのための環境変数の配列。 現在の PHP プロセスと同じ環境変数を使用する場合は NULL を指定します。
other_options
その他の追加オプションを指定することが可能です。 現在サポートされているオプションは次の通りです。
  • suppress_errors (windows のみ): TRUE にすると、この関数が出力するエラーを抑制します。
  • bypass_shell (windows のみ): TRUE にすると、cmd.exe シェルをバイパスします。
  • blocking_pipes (windows のみ): TRUE に設定すると、パイプを強制的に切断します。
  • create_process_group (Windows のみ): TRUE に設定すると、 子プロセスが CTRL イベントを ハンドルすることを許可します。
  • create_new_console (windows のみ): 新しいプロセスは親の console を継承せず、新しい console を持ちます。

返値

プロセスを表すリソースを返します。このリソースは、使用し終えた際に proc_close() を使用して開放する必要があります。 失敗した場合は FALSE を返します。

注意

注意: Windows における互換性: 2 (stderr) よりも大きな番号のディスクリプタは 子プロセスに継承可能なハンドルとして渡されますが、 Windows のアーキテクチャは、ファイルディスクリプタの番号と より低レベルなハンドルを関連付けないので、子プロセスは、 それらのハンドルにアクセスする術を持ちません。stdin, stdout, stderr は期待通り動きます。
注意: もし単方向(一方向)のパイプを利用したいだけでしたら、 popen() を使うほうがより簡単です。

更新履歴

バージョン 説明
7.4.4 other_options パラメータに オプション create_new_console が追加されました。
7.4.0 proc_open() 関数は、 cmd に array を渡せるようになりました。
7.4.0 other_options パラメータに オプション create_process_group が追加されました。

サンプル

例1 A proc_open() の例

$descriptorspec = array(    0 => array("pipe", "r"),  // stdin は、子プロセスが読み込むパイプです。    1 => array("pipe", "w"),  // stdout は、子プロセスが書き込むパイプです。    2 => array("file", "/tmp/error-output.txt", "a") // はファイルで、そこに書き込みます。 ); $cwd = '/tmp'; $env = array('some_option' => 'aeiou'); $process = proc_open('php', $descriptorspec, $pipes, $cwd, $env); if (is_resource($process)) {     // $pipes はこの時点で次のような形を取っています。     // 0 => 子プロセスの stdin に繋がれた書き込み可能なハンドル     // 1 => 子プロセスの stdout に繋がれた読み込み可能なハンドル     // すべてのエラー出力は /tmp/error-output.txt に書き込みされます。     fwrite($pipes[0], ' ');    fclose($pipes[0]);    echo stream_get_contents($pipes[1]);    fclose($pipes[1]);    // デッドロックを避けるため、proc_close を呼ぶ前に    // すべてのパイプを閉じることが重要です。    $return_value = proc_close($process);    echo "command returned $return_value\n";}?>

上の例の出力は、たとえば以下のようになります。

Array ( [some_option] => aeiou [PWD] => /tmp [SHLVL] => 1 [_] => /usr/local/bin/php ) command returned 0

例2 proc_open() 関数の癖(Windows限定)

次のプログラムで、ファイル filename.txt にある search というテキストを検索し、結果を出力したいのですが、 実際にはかなり異なる振る舞いをします。

$descriptorspec = [STDIN, STDOUT, STDOUT]; $cmd = '"findstr" "search" "filename.txt"'; $proc = proc_open($cmd, $descriptorspec, $pipes); proc_close($proc);

上の例の出力は以下となります。

'findstr" "search" "filename.txt' is not recognized as an internal or external command, operable program or batch file.

この振る舞いを避けるには、 cmd を追加のクォートで囲めば通常は十分です:

$cmd = '""findstr" "search" "filename.txt""';

参考

  • popen() - プロセスへのファイルポインタをオープンする
  • exec() - 外部プログラムを実行する
  • system() - 外部プログラムを実行し、出力を表示する
  • passthru() - 外部プログラムを実行し、未整形の出力を表示する
  • stream_select() - select() システムコールと同等の操作を、 ストリームの配列に対して tv_sec と tv_usec で指定されたタイムアウト時間をもって行う
  • バックティック演算子
  • ワード検索


    ※入力キーワードが、関数名・説明文・タグに含まれるものを検索

    関数名アルファベット別

    A B C D E F G H I J
    K L M N O P Q R S T
    U V W X Y Z _

    最終更新一覧

    stristr
     大文字小文字を区別せず文字列を検索し、ヒット箇所以降(あるいは以前)の文字列を返却

    stripslashes
     バックスラッシュでエスケープされた文字列から、バックスラッシュを取り除く

    stripos
     大文字小文字を区別せずに文字列が最初に現れる位置を取得する

    stripcslashes
     addcslashes() でクォートされた文字列をアンクォートする

    strip_tags
     文字列から HTML と PHP のタグを除去して返却

    strcspn
     指定した文字が最初に現れる位置を調べる

    strcoll
     ロケールに基づいて2つの文字列を比較し同じか(あるいは大小)を判定する

    strcmp
     2つの文字列を比較し同じか(あるいは大小)を判定する

    strchr
     strstr() のエイリアス

    strcasecmp
     2つの文字列を比較(大文字小文字を区別せず同じとみなす)

    カテゴリー一覧

    PHP の振る舞いの変更
    音声フォーマットの操作
    認証サービス
    コマンドライン関連
    圧縮およびアーカイブ
    暗号
    データベース関連
    日付および時刻関連
    ファイルシステム
    自然言語および文字エンコーディング
    画像処理および作成
    メール関連
    数学
    テキスト以外の MIME 型
    プロセス制御
    その他の基本モジュール
    その他のサービス
    検索エンジン用の拡張モジュール
    サーバー固有のモジュール
    セッション関連
    テキスト処理
    変数・データ型関連
    ウェブサービス
    Windows 用のモジュール
    XML 操作
    GUI用の拡張モジュール