web-dev-qa-db-ja.com

PHP exec()とsystem()とpassthru()

違いは何ですか?

各機能に特定の状況や理由はありますか?もしそうなら、あなたはそれらの状況のいくつかの例を挙げることができますか?

PHP.netによると、これらは外部プログラムを実行するために使用されています。 参照を参照 私が見た例から、明らかな違いは見当たりません。

単純にスクリプト(bashまたはpython)を実行する場合、どの機能を使用することをお勧めしますか?

297
codingbear

彼らはわずかに異なる目的を持っています。

  • exec() はシステムコマンドを呼び出し、おそらく自分自身で出力を処理するためのものです。
  • system() はシステムコマンドを実行し、即座に出力を表示するためのものです - おそらくテキストです。
  • passthru() はシステムコマンドを実行するためのもので、そこから生の戻り値を取得します - おそらく何らかのバイナリです。

とにかく、私はあなたがそれらのどれも使わないことを勧めます。それらはすべて非常に移植性の低いコードを生成します。

178
Kalium

http://php.net/ && Chipmunkninja から導かれるように:

system() 関数

PHPのシステム関数は、実行するコマンドの文字列引数と、そのコマンドに渡したい引数を取ります。この関数は指定されたコマンドを実行し、結果のテキストを出力ストリームに出力します(Webサーバー環境でのHTTP出力、またはコマンドラインツールとしてPHPを実行している場合はコンソール)。この関数がテキスト出力を発行する場合、この関数の戻りはプログラムからの出力の最後の行です。

exec() 関数

システム関数は非常に便利で強力ですが、最大の問題の1つは、プログラムからの結果テキストがすべて出力ストリームに直接送られることです。結果のテキストをフォーマットして別の方法で表示したい場合や、まったく表示しない場合があります。

このため、PHPのexec関数は完全に適応されています。実行されているプログラムによって生成されたすべてのテキストを自動的に出力ストリームにダンプする代わりに、このテキストを関数の2番目のパラメータで返される配列に入れることができます。

Shell_exec() 関数

これまで実行してきたプログラムのほとんどは、多かれ少なかれ実際のプログラムでした1。しかし、WindowsとUnixのユーザーが操作する環境は、実際にはこれよりはるかに豊かです。 Windowsユーザーは、Windowsコマンドプロンプトプログラム、cmd.exeを使用することができます。このプログラムは、コマンドシェルとして知られています。

passthru() 関数

PHPがこれまでに見てきたものと同様に提供する魅力的な機能の1つは、パススルー機能です。この関数は、他の関数と同様に、あなたが指示したプログラムを実行します。ただし、このプログラムからの生の出力を、PHPが現在動作している出力ストリーム(WebサーバーシナリオではHTTP、コマンドラインバージョンのPHPではShell)に直ちに送信します。 ).

proc_open() 関数と popen() 関数

proc_open()はpopen()に似ていますが、プログラムの実行に対してより高度な制御を提供します。 cmdはシェルによって実行されるコマンドです。 descriptororspecは、キーがディスクリプタ番号を表し、値がPHPがそのディスクリプタを子プロセスに渡す方法を表すインデックス付き配列です。パイプは、作成された任意のパイプの最後の部分に対応するファイルポインタのインデックス付き配列に設定されます。戻り値はプロセスを表すリソースです。使い終わったらproc_close()を使って解放してください。

118
Dinesh Saini

前の答えはすべて少し混乱しているか不完全であるように見えたので、ここに違いの表があります...

+----------------+-----------------+----------------+----------------+
|    Command     | Displays Output | Can Get Output | Gets Exit Code |
+----------------+-----------------+----------------+----------------+
| system()       | Yes (as text)   | Last line only | Yes            |
| passthru()     | Yes (raw)       | No             | Yes            |
| exec()         | No              | Yes (array)    | Yes            |
| Shell_exec()   | No              | Yes (string)   | No             |
| backticks (``) | No              | Yes (string)   | No             |
+----------------+-----------------+----------------+----------------+
  • 「ディスプレイ出力」とは、ブラウザに出力を送ることを意味します(コマンドラインから実行する場合はコマンドライン出力)。
  • 「Can Get Output」は、コマンドの出力を取得してそれをPHP変数に代入できることを意味します。
  • 「終了コード」は、コマンドによって返される特別な値です(「リターンステータス」とも呼ばれます)。ゼロは通常それが成功したことを意味し、他の値は通常エラーコードです。

注意が必要なその他の事項

  • Shell_exec()とbackticks演算子は同じことをします。
  • Proc_open()とpopen()もあります。これらは実行中のコマンドで対話的にストリームを読み書きすることを可能にします。
  • エラーメッセージもキャプチャ/表示したい場合は、コマンド文字列に "2>&1"を追加してください。
  • 問題のある文字を含む可能性があるコマンド引数をエスケープするには、escapeshellcmd()を使用してください。
  • 出力を格納するためにexec()に$ output変数を渡した場合、$ outputが空でなければ、新しい出力が追加されます。そのため、最初に($ output)設定を解除する必要があるかもしれません。
77
orrd

コマンドが返す可能性のある出力をどのように処理したいか、およびPHPスクリプトを呼び出し先プログラムの完了を待つかどうかは、実際のところすべてです。

  • execはコマンドを実行し、出力を呼び出し元に渡します(またはオプションの変数に返します)。

  • passthruは、コマンドを実行するという点でexec()関数と似ています。 Unixコマンドからの出力がバイナリデータであり、ブラウザに直接返す必要がある場合は、この関数をexec()またはsystem()の代わりに使用する必要があります。

  • systemは外部プログラムを実行して出力を表示しますが、最後の行だけを表示します。

コマンドを実行する必要があり、コマンドからのすべてのデータが何の干渉もなしに直接返されるようにするには、passthru()関数を使用します。

18
Cody Caughlan

コマンドラインからPHPスクリプトを実行している場合、passthru()には1つの大きな利点があります。それはあなたがvimdialogなどのようなスクリプト/プログラムを実行することを可能にします。

system()exec()を使ってこれらのスクリプトやプログラムを実行しても、うまくいきません。

Gotcha:どういうわけか、PHPではlesspassthru()で実行することはできません。

6
Matt