PHP は、他のプログラミング言語と同様に、プログラム内で外部コマンドを呼び出すことができます。これは非常に簡単です。1 つまたはいくつかの関数を使用するだけです。 前提条件 PHPは基本的にWEBプログラムの開発に使用されるため、セキュリティは人々が考慮する重要な側面となっています。 そこで、PHP 設計者は PHP への扉、つまりセーフ モードを追加しました。 セーフ モードで実行する場合、PHP スクリプトには次の 4 つの制限が適用されます: 1. 外部コマンドの実行 2. ファイルを開く際にはいくつかの制限があります。 3.mysqlデータベースに接続します 4. HTTPベースの認証セーフ モードでは、特定のディレクトリ内の外部プログラムのみが実行でき、他のプログラムへの呼び出しは拒否されます。 このディレクトリは、safe_mode_exec_dir ディレクティブを使用して php.ini ファイル内で使用することも、PHP のコンパイル時に追加することもできます。 --with-exec-dir オプションを指定します。デフォルトは /usr/local/php/bin です。 結果を出力するはずの外部コマンド (PHP スクリプトにエラーがないことを意味します) を呼び出したにもかかわらず空白が返された場合は、PHP がセーフ モードで実行されている可能性があります。 PHP で外部コマンドを呼び出すには、次の 3 つの方法を使用できます: 1) PHP が提供する特別な関数を使用する PHP は、外部コマンドを実行するために、system()、exec()、および passthru() という合計 3 つの特殊な関数を提供します。 1.システム() プロトタイプ: 文字列システム (文字列コマンド [, int return_var]) system() 関数は他の言語の関数と似ており、指定されたコマンドを実行し、結果を出力して返します。 2 番目のパラメーターはオプションであり、コマンドの実行後にステータス コードを取得するために使用されます。 例: リーリー2.実行() プロトタイプ: string exec (string command [, string array [, int return_var]]) exec () 関数は system () と似ていますが、指定されたコマンドを実行しますが、結果は出力されず、結果の最後の行が返されます。コマンド結果の最後の行のみを返しますが、2 番目のパラメーター配列を使用すると完全な結果を取得できます。 方法は結果をコントロールすることです 結果は配列の末尾に 1 行ずつ追加されます。したがって、配列が空でない場合は、呼び出す前に unset() を使用して配列をクリアするのが最善です。第3パラメータは第2パラメータを指定した場合のみ、コマンド実行時のステータスコードを取得できます。 。 例: リーリー3. パススルー() プロトタイプ: void passthru (string command [, int return_var]) passthru() はコマンドを呼び出すだけで結果は返さず、コマンドの実行結果をそのまま標準出力装置に直接出力します。したがって、 passthru() 関数は、pbmplus (Unix の画像処理プログラム) などのプログラムを呼び出すためによく使用されます。 ツール、出力 2 (16 進形式の生画像のストリーム)。コマンド実行時のステータスコードも取得できます。 例: リーリー2) Popen() 関数を使用してプロセスを開きます 上記のメソッドは単にコマンドを実行することしかできませんが、コマンドと対話することはできません。 場合によっては、コマンドに何かを入力する必要があります。たとえば、Linux システム ユーザーを追加する場合、su を呼び出して現在のユーザーを root に変更する必要があり、su コマンドはコマンド ラインに存在する必要があります。 rootのパスワードを入力します。この場合、明らかに上記の方法を使用することはできません。 popen() 関数は、プロセス パイプを開いて指定されたコマンドを実行し、ファイル ハンドルを返します。ファイルハンドルが返されるので、読み書きが可能です。 PHP3 では、この種類のハンドルに対して実行できる操作は 1 つだけです モードは書き込みまたは読み取りのいずれかで、PHP4 以降は読み取りと書き込みを同時に行うことができます。 ハンドルが 1 つのモード (読み取りまたは書き込み) で開かれていない限り、ハンドルを閉じるには pclose() 関数を呼び出す必要があります。 例 1: リーリー例 2: リーリー3) バッククォート (`、つまり、キーボードの ESC キーの下にあるバックティック、~ と同じです) を使用します。 このメソッドはこれまで PHP では文書化されておらず、秘密のテクニックとして存在していました。 2 つのバックティックを使用して、実行するコマンドを式として囲みます。この式の値は、コマンドの実行結果になります。 例: リーリー出力結果: ハント.gif ハント.ppm jpg.htm jpg.jpg パススルー.phpセキュリティとタイムアウトという 2 つの問題を考慮する必要があります。 セキュリティ。 たとえば、小規模なオンライン ストアがあるため、販売可能な製品のリストがファイルに保存されています。 ユーザーが電子メール アドレスを入力して製品リストを送信できるフォームを含む HTML ファイルを作成します。 PHP の mail() 関数を使用したことがない (または聞いたことがない) と仮定して、Linux/Unix システムのメール プログラムを呼び出してこのファイルを送信します。 例: リーリーこのコードには、実際には非常に大きなセキュリティ上の脆弱性があります。 悪意のあるユーザーがそのような電子メール アドレスを入力した場合: リーリーそして、このコマンドは最終的に次のようになります: リーリー怖いので、自分のコンピュータでは試さないでください。そうしないと、想像するほどひどい結果にはなりません。 php提供了两个函数:EscapeShellCmd()和EscapeShellArg()。 函数EscapeShellCmd把一个字符串 中所有可能瞒过Shell而去执行另外一个命令的字符转义。这些字符在Shell 中是有特殊含义的,象分号(),重定向(>)和从文件读入 ( 再说下超时问题。 如果要执行的命令要花费很长的时间,那么应该把这个命令放到系统的后台去运行。 默认情况下,象system()等函数要等到这个命令运行完才返回(实际上是要等命令的输出结果),这肯定会引起PHP脚本的超时。 解决方法,把命令的输出重定向到另外一个文件或流中。 例如: <?php system("/usr/local/bin/order_proc > /tmp/null &"); ?> ログイン後にコピー |