関数・クラス解説
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 など) をあらわすストリームリソース。
- 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""';
参考
ワード検索
※入力キーワードが、関数名・説明文・タグに含まれるものを検索関数名アルファベット別
最終更新一覧
●stristr
大文字小文字を区別せず文字列を検索し、ヒット箇所以降(あるいは以前)の文字列を返却
●stripslashes
バックスラッシュでエスケープされた文字列から、バックスラッシュを取り除く
●stripos
大文字小文字を区別せずに文字列が最初に現れる位置を取得する
●stripcslashes
addcslashes() でクォートされた文字列をアンクォートする
●strip_tags
文字列から HTML と PHP のタグを除去して返却
●strcspn
指定した文字が最初に現れる位置を調べる
●strcoll
ロケールに基づいて2つの文字列を比較し同じか(あるいは大小)を判定する
●strcmp
2つの文字列を比較し同じか(あるいは大小)を判定する
●strchr
strstr() のエイリアス
●strcasecmp
2つの文字列を比較(大文字小文字を区別せず同じとみなす)
カテゴリー一覧
PHP の振る舞いの変更
音声フォーマットの操作
認証サービス
コマンドライン関連
圧縮およびアーカイブ
暗号
データベース関連
日付および時刻関連
ファイルシステム
自然言語および文字エンコーディング
画像処理および作成
メール関連
数学
テキスト以外の MIME 型
プロセス制御
その他の基本モジュール
その他のサービス
検索エンジン用の拡張モジュール
サーバー固有のモジュール
セッション関連
テキスト処理
変数・データ型関連
ウェブサービス
Windows 用のモジュール
XML 操作
GUI用の拡張モジュール