Linux 上で PHP を使用して外部コマンドを実行する方法

墨辰丷
リリース: 2023-03-28 06:44:02
オリジナル
1361 人が閲覧しました

この記事では主に Linux 上で PHP が外部コマンドを実行する方法を紹介します。興味のある方はぜひ参考にしてください。

ディレクトリ:

1. PHP での外部コマンドの呼び出しの概要
2. セキュリティの問題について
3. タイムアウトの問題について
4. PHP が Linux 環境でコマンドを実行するときに発生する問題について

1、PHP での外部コマンドの呼び出しの概要

PHP で外部コマンドを呼び出すには、1> 特別な関数を呼び出す、2>gt;popen() 関数を使用してプロセスを開きます。実現するには:

方法 1: PHP が提供する特殊な関数を使用する (4 つ):

PHP には、外部コマンドを実行するための 4 つの特殊な関数が用意されています: exec()、system()、passthru()、shell_exec( )

1) exec()

プロトタイプ: string exec ( string $command [, array &$output [, int &$return_var ] )

説明: exec はシステムの実行時に結果を出力しません外部コマンドですが、結果の最後の行を返します。結果を取得したい場合は、2 番目のパラメーターを使用して、指定した配列に結果を出力できます。この配列内の 1 つのレコードは出力の行を表します。つまり、出力結果が 20 行ある場合、この配列には 20 レコードが含まれることになります。したがって、異なるシステム外部コマンドを呼び出した結果を繰り返し出力する必要がある場合は、出力時に配列 unset($output) をクリアするのが最善です。各システム外部コマンドの結果。混乱を避けるため。 3 番目のパラメータは、コマンド実行のステータス コードを取得するために使用されます。通常、実行が成功した場合は 0 が返されます。

<?php
  exec("dir",$output);
  print_r($output);
?>
ログイン後にコピー

2) system()

プロトタイプ: string system ( string $command [, int &$return_var ] )

説明: system と exec の違いは、システムがシステムの外にあることです。実行システム 命令されると、指定されたコマンドを実行し、結果を出力して返します。 2 番目のパラメーターはオプションであり、コマンドの実行後にステータス コードを取得するために使用されます。

<?php
system("pwd",$result);
print $result;//输出命令的结果状态码
?>
ログイン後にコピー

2 番目のパラメーターの結果ステータス コードの簡単な説明:

0 が返された場合、操作は成功です。

Bash では、致命的なシグナルでエラーが発生した場合、bash は 128 を返します。 +信号番号を戻り値として返します。

コマンドが見つからない場合は、127が返されます。

コマンドが見つかっても実行できない場合は、126が返されます。

さらに、Bash自体は最後の命令の戻り値を返します。

実行中にエラーが発生した場合は、ゼロ以外の値が返されます。

致命的なシグナル: 128 + Signo
コマンドが見つからない: 127
実行できない: 126
シェルスクリプトが正常に実行されました: 最後のコマンドの終了ステータスを返します
実行中の致命的: ゼロ以外を返します

3) passthru()

プロトタイプ: void passthru ( string $command [, int &$return_var ] )

説明: パススルーとシステムの違い。パススルーは値を返さずに結果をブラウザに直接出力します。 、画像データなどのバイナリデータを出力できます。 2 番目のパラメータはオプションであり、ステータス コードです。

<?php
header("Content-type:image/gif");
passthru("/usr/bin/ppm2tiff /usr/share/tk8.4/demos/images/teapot.ppm");
?>
ログイン後にコピー

4)shell_exec()

プロトタイプ:stringshell_exec(string$cmd)

説明:コマンド$cmdを直接実行します

<?php
$output = shell_exec(&#39;ls -lart&#39;);
echo "<pre class="brush:php;toolbar:false">$output
"; ?>
ログイン後にコピー

方法 2: 逆方向スキミング番号

プロトタイプ: システム外部コマンドを実行するためのバッククォート ` (同じキーに ~ を含む)

説明: このメソッドを使用してシステム外部コマンドを実行する場合は、shell_exec 関数が使用可能であることを確認し、それ以外の場合はこのメソッドバッククォートはシステムの外部でコマンドを実行します。

<?php
  echo `dir`;
?>
ログイン後にコピー

方法 3: Popen() 関数を使用してプロセスを開きます

プロトタイプ: resource Popen ( string $command , string $mode )

説明: コマンドを操作できます。前に紹介した方法では、単にコマンドを実行するだけで、コマンドと対話することはできません。たとえば、システム ユーザーを追加する場合、su を呼び出して現在のユーザーを root ユーザーに変更する必要がある場合があります。su コマンドではコマンド ラインに root パスワードを入力する必要があります。この場合、前述の方法を使用することは明らかに不可能です。

popen() 関数は、指定されたコマンドを実行するためにプロセス パイプを開き、読み取りおよび書き込みが可能なファイル ハンドルを返します。戻り値は fopen() 関数と同じで、ファイル ポインターを返します。単一モードを使用してオープン (読み取りまたは書き込み) を行っていない限り、pclose() 関数を使用してクローズする必要があります。このポインタは、fgets()、fgetss()、fwrite() によって呼び出すことができます。エラーが発生した場合は FALSE を返します。

<?php
error_reporting(E_ALL);
 
/* Add redirection so we can get stderr. */
$handle = popen(&#39;/path/to/executable 2>&1&#39;, &#39;r&#39;);
echo "&#39;$handle&#39;; " . gettype($handle) . "\n";
$read = fread($handle, 2096);
echo $read;
pclose($handle);
?>
ログイン後にコピー

2. セキュリティ問題について:

WEBプログラム開発には基本的にPHPが使用されるため、セキュリティは人々が考慮する重要な側面となっています。

そこで、PHP の設計者は、PHP にセーフ モードという扉を追加しました。

php.iniでsafe_mode = Onに設定します

如果运行在安全模式下,那么PHP脚本中将受到如下四个方面的限制:

执行外部命令
在打开文件时有些限制
连接MySQL数据库
基于HTTP的认证

在安全模式下,只有在特定目录中的外部程序才可以被执行,对其它程序的调用将被拒绝。这个目录可以在php.ini文件中用safe_mode_exec_dir指令,或在编译PHP 是加上–with-exec-dir选项来指定,默认是/usr/local/php/bin。

当你使用这些函数来执行系统命令时,可以使用escapeshellcmd()和escapeshellarg()函数阻止用户恶意在系统上执行命令,escapeshellcmd()针对的是执行的系统命令,而escapeshellarg()针对的是执行系统命令的参数。这两个参数有点类似addslashes()的功能。

三、关于超时问题

当执行命令的返回结果非常庞大时,可以需要考虑将返回结果输出至其他文件,再另行读取文件,这样可以显著提高程序执行的效率。

如果要执行的命令要花费很长的时间,那么应该把这个命令放到系统的后台去运行。但在默认情况下,象system()等函数要等到这个命令运行完才返回(实际上是在等命令的输出结果),这肯定会引起PHP脚本的超时。解决的办法是把命令的输出重定向到另外一个文件或流中,如:

<?php
system("/usr/local/bin/order_proc > /tmp/abc ");
?>
ログイン後にコピー

但我调用的DOS命令需要几分钟的时间,而且为了批处理不能简单的把结果写入文件了事,要顺序执行以下的程序

PHP设置了调用系统命令的时间限制,如果调用命令超时,虽然这个命令还是会被执行完,但PHP没有得到返回值,被终止了(最可恨的是,不显示任何错误)

修改php.ini并重启Apache以允许系统命令运行更长的时间

max_execution_time = 600

四、关于PHP运行linux环境中命令出现的问题

php一般是以apache用户身份去执行的,也可能是www用户,把apache加入到存储你文件的父文件夹属组里去,然后改该父文件夹权限为775,这样属组成员就有写的权限,而apache属于这个组就可以改写该目录下所有文件的权限。

例如:chown www:www dirName

这样dirName目录才能被php所控制

注意:改apache/php的运行用户方法不安全

另外即使文件或目录已经是www,php的安全设置也都照顾到,一些自己安装linux的命令仍然可能无法运行,例如我曾经安装的ffmpeg软件,原因就是linux的运行权限问题,即使ffmpeg有www权限设置,但由于ffmpeg所依赖的库文件是不允许www用户运行,所以php运行此程序仍然会报127或126错误,通过 ldd 命令可以查看ffmpeg命令依赖的库情况。

这个时候就必须对ffmpeg的依赖库经行设置。具体方法属于linux管理中的话题,这里不就讨论了。

以上就是本文的全部内容,希望对大家的学习有所帮助。


相关推荐:

linux后台运行node服务指令步骤方法

Linux中正则表达式使用详解

php获取linux命令结果的方法

以上がLinux 上で PHP を使用して外部コマンドを実行する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート