ホームページ  >  記事  >  バックエンド開発  >  PHPが外部コマンドを呼び出せない場合の対処方法

PHPが外部コマンドを呼び出せない場合の対処方法

WBOY
WBOYオリジナル
2016-07-25 08:58:471243ブラウズ
  1. exec(""/bin/ls -l"");
  2. exec(""/bin/ls -l"", $res);
  3. #$resはデータ、各要素は結果の行を表します
  4. exec(""/bin/ls -l"", $res, $rc);
  5. #$rc の値はコマンド /bin/ls -l のステータス コードです。成功した場合、通常は 0
  6. ?>
コードをコピー

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

例:

  1. header(""Content-type: image/gif"");
  2. passthru(""./ppmtogif Hunte.ppm"");
  3. ?>
コードをコピー

2、popen() 関数を使用してプロセスを開きます 上記のメソッドは単にコマンドを実行することしかできませんが、コマンドと対話することはできません。ただし、コマンドに何かを入力する必要がある場合があります。たとえば、Linux システム ユーザーを追加する場合、su を呼び出して現在のユーザーを root に変更する必要があり、su コマンドはコマンド ラインに root パスワードを入力する必要があります。この場合、明らかに上記の方法を使用することはできません。

popen() 関数は、プロセス パイプを開いて指定されたコマンドを実行し、ファイル ハンドルを返します。ファイルハンドルが返されるので、読み書きが可能です。 PHP3 では、この種のハンドルは書き込みまたは読み取りの 1 つの操作モードでのみ使用できますが、PHP4 以降は読み取りと書き込みを同時に行うことができます。ハンドルが 1 つのモード (読み取りまたは書き込み) で開かれていない限り、ハンドルを閉じるには pclose() 関数を呼び出す必要があります。

例 1:

  1. $fp=popen(""/bin/ls -l"", ""r"");
  2. ?>
コードをコピー

例 2:

  1. /* PHP でシステム ユーザーを追加する方法
  2. james という名前のユーザーを追加します。
  3. root パスワードは非常に適切です。参考のみ
  4. */
  5. $sucommand = ""su --login root --command"";
  6. $useradd = ""useradd "";
  7. $rootpasswd = ""verygood"";
  8. $user = ""james "";
  9. $user_add = sprintf(""%s ""%s %s"""",$sucommand,$useradd,$user);
  10. $fp = @popen($user_add,""w"") ;
  11. @fputs($fp,$rootpasswd);
  12. @pclose($fp);
  13. ?>
コードをコピー

3、バックティック (`、画面上の ESC キーの下にあります) を使用します。キーボード That と ~ は同じ上にあります) 方法は非常に簡単です。実行するコマンドを 2 つのバックティックで囲み、この式の値がコマンドの実行結果になります。のように:

  1. $res=`/bin/ls -l`;
  2. echo '
    '.$res.'
    ';
  3. ?>
コードをコピーします

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

  1. system(""mail $to < products.txt"");
  2. echo ""製品カタログがあなたのメールボックス $to に送信されました"";
  3. ?>
コードをコピー

このコードを使用しても一般ユーザーに危険はありませんが、実際には非常に大きなセキュリティ上の脆弱性が存在します。悪意のあるユーザーがそのような EMAIL アドレスを入力した場合: '--bla mail somebody@domain.com ) とファイルから読み取ります ()

タイムアウトの問題 コマンドの実行に時間がかかる場合は、システムのバックグラウンドでコマンドを実行する必要があります。 ただし、デフォルトでは、system() などの関数は、コマンドの実行が完了するまで待機してから戻ります (実際には、コマンドの出力を待つ必要があります)。そのため、PHP スクリプトがタイムアウトすることは間違いありません。

解決策: コマンドの出力を別のファイルまたはストリームにリダイレクトします。例:

  1. system(""/usr/local/bin/order_proc > /tmp/null &"");
  2. ?>
コードをコピー


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