Maison > Article > développement back-end > Comment exécuter des commandes externes avec PHP sous Linux
Cet article présente principalement comment PHP exécute les commandes externes sous Linux. Les amis intéressés peuvent s'y référer. J'espère qu'il sera utile à tout le monde.
Répertoire :
1. Introduction à l'appel de commandes externes en PHP
2 À propos des problèmes de sécurité
3. . À propos du problème de délai d'attente
4. À propos des problèmes qui surviennent lorsque PHP exécute des commandes dans l'environnement Linux
1. Introduction à l'appel de commandes externes en PHP
Pour appeler des commandes externes en PHP, vous pouvez utiliser trois méthodes : 1> appeler une fonction spéciale, 2> la fonction popen() pour ouvrir le processus :
Méthode 1 : Utiliser les fonctions spécialisées (quatre) fournies par PHP :
PHP fournit 4 fonctions spécialisées pour exécuter des commandes externes : exec(), system (), passthru(), shell_exec()
1) exec()
Prototype : string exec ( string $command [, array &$output [, int &$return_var ] )
Explication : Lorsque exec exécute une commande externe au système, il n'affiche pas le résultat, mais renvoie la dernière ligne du résultat. Si vous souhaitez obtenir le résultat, vous pouvez utiliser le deuxième paramètre pour le sortir dans le tableau spécifié. Un enregistrement de ce tableau représente une ligne de sortie. Autrement dit, si le résultat de sortie comporte 20 lignes, alors ce tableau aura 20 enregistrements. Par conséquent, si vous devez afficher à plusieurs reprises les résultats de l'appel de différentes commandes externes du système, il est préférable d'effacer le tableau ($output) lors de la sortie. les résultats de chaque commande externe du système. Pour éviter toute confusion. Le troisième paramètre est utilisé pour obtenir le code d'état de l'exécution de la commande. Généralement, 0 est renvoyé si l'exécution est réussie.
<?php exec("dir",$output); print_r($output); ?>
2) système()
Prototype : système de chaînes (chaîne $command [, int &$return_var ] )
Explication : La différence entre system et exec est que lorsque le système exécute une commande externe au système, il exécute la commande donnée, génère et renvoie les résultats. Le deuxième paramètre est facultatif et est utilisé pour obtenir le code d'état après l'exécution de la commande.
<?php system("pwd",$result); print $result;//输出命令的结果状态码 ?>
Une brève introduction au code d'état du résultat du deuxième paramètre :
Si 0 est renvoyé, il exécute Success,
Dans Bash, lorsqu'une erreur se produit dans un signal fatal, bash renverra 128+numéro de signal comme valeur de retour.
Si la commande n'est pas trouvée, 127 sera renvoyée.
Si la commande est trouvée mais que la commande n'est pas exécutable, 126 sera renvoyée.
De plus, Bash renvoie lui-même la valeur de retour de la dernière instruction.
Si une erreur survient lors de l'exécution, une valeur non nulle sera renvoyée.
Fatal Signal : 128 + signo
Impossible de trouver la commande : 127
Impossible de ne pas exécuter : 126
Script Shell exécuté avec succès : renvoie l'état de sortie de la dernière commande
Fatal lors de l'exécution : renvoie une valeur non nulle
3) passthru()
Prototype : void passthru ( string $ command [, int &$return_var ] )
Explication : La différence entre passthru et système, passthru génère directement les résultats au navigateur sans renvoyer aucune valeur, et il peut générer des données binaires, telles que des données d'image. Le deuxième paramètre est facultatif et est le code d'état.
<?php header("Content-type:image/gif"); passthru("/usr/bin/ppm2tiff /usr/share/tk8.4/demos/images/teapot.ppm"); ?>
4) shell_exec()
Prototype : chaîne shell_exec (chaîne $cmd )
Instructions : Exécutez directement la commande $cmd
<?php $output = shell_exec('ls -lart'); echo "<pre class="brush:php;toolbar:false">$output"; ?>
Méthode 2 : Backticks
Prototype : backtick` (dans la même clé que ~) exécute les commandes externes du système
Remarque : lorsque vous utilisez cette méthode pour exécuter des commandes externes du système, assurez-vous que la fonction shell_exec est disponible, sinon il est impossible d'utiliser ce backtick pour exécuter des commandes externes au système.
<?php echo `dir`; ?>
Méthode 3 : Utilisez la fonction popen() pour ouvrir le processus
Prototype : ressource popen (string $command, string $mode)
Description : Capable d'interagir avec les commandes. La méthode introduite précédemment peut simplement exécuter la commande, mais ne peut pas interagir avec la commande. Parfois, vous devez saisir quelque chose dans la commande. Par exemple, lors de l'ajout d'un utilisateur système, vous devez appeler su pour remplacer l'utilisateur actuel par l'utilisateur root. La commande su doit saisir le mot de passe root sur la ligne de commande. Dans ce cas, il n’est évidemment pas possible d’utiliser la méthode évoquée précédemment.
La fonction popen() ouvre un tube de processus pour exécuter la commande donnée et renvoie un descripteur de fichier qui peut être lu et écrit. La valeur de retour est la même que celle de la fonction fopen(), renvoyant un pointeur de fichier. A moins qu'un seul mode ne soit utilisé pour l'ouverture (lecture ou écriture), il doit être fermé à l'aide de la fonction pclose(). Ce pointeur peut être appelé par fgets(), fgetss(), fwrite(). En cas d'erreur, renvoie FALSE.
<?php error_reporting(E_ALL); /* Add redirection so we can get stderr. */ $handle = popen('/path/to/executable 2>&1', 'r'); echo "'$handle'; " . gettype($handle) . "\n"; $read = fread($handle, 2096); echo $read; pclose($handle); ?>
2. Concernant les problèmes de sécurité :
Puisque PHP est essentiellement utilisé Pour le développement de programmes WEB, la sécurité est devenue un aspect important pris en compte.
Les concepteurs de PHP ont donc ajouté une porte à PHP : le mode sans échec.
Définissez safe_mode = On dans php.ini
如果运行在安全模式下,那么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管理中的话题,这里不就讨论了。
以上就是本文的全部内容,希望对大家的学习有所帮助。
相关推荐:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!