作为一个服务端语言,PHP不可避免会有在程序中执行外部程序的需求,那么这篇文章就总结一下 PHP 执行外部程序的函数以及需要注意的坑。
执行运算符 与 shell_exec()
通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。PHP 执行运算符,使用反引号表示。PHP 会尝试将反引号的内容当做 Shell
命令来执行,并将其输出的信息返回(既,外部程序的执行输出会返回给而不是输出到终端)。执行运算符与函数 shell_exec()
相同(可以理解为是别名的关系)。
需要注意的是,在 php.ini
中如果禁用了 shell_exec()
函数,则执行运算符也会失效。
参数说明
shell_exec(string $cmd): string || null
-
cmd 要执行的命令,与双引号一样的是,执行运算符支持解析变量。
返回值
外部程序的标准输出,如果执行过程中发生错误或进程不产生输出,则返回 null。
因为不产生输出和发生错误都会返回 null,所以,使用此函数的返回值无法检测外部程序是否执行成功,如果想获取程序执行的退出码,可以使用 exec()
函数的 return_var
参数。
例子
<?php
// 执行运算符与 shell_exec 效果一样
var_dump(`ls /home`);
var_dump(shell_exec('ls /home'));
// 执行错误的命令 输出 Null
var_dump(shell_exec('ls /homes'));
?>
执行后终端输出如下内容:
dbkuaizi-alpine:/home# php test/demo.php
string(13) "project
test
"
string(13) "project
test
"
ls: /homes: No such file or directory
NULL
system
执行外部程序,并显示外部程序的输出结果。
如果运行在 PHP 服务器模块中,system()
函数还会尝试在每行输出完毕后,自动刷新 Web 服务器输出的缓存。
参数说明
system(string $command[, int &$return_var = ?]): string
-
command 要执行的命令 -
return_var 如果提供此参数,则外部命令执行后的状态将会被设置在此变量中。
返回值
成功则返回命令输出的最后一行,失败则返回 false。
若要判断命令是否成功执行,需要要判断状态码是否为 0
,不要通过返回值是否等于 false 来判断执行是否成功。因为实际测试中,执行失败的返回值是空字符串。
例子
<?php
$a = system('ls /home',$b);
var_dump($a,$b);
echo '------'.PHP_EOL;
$c = system('ll /home',$d);
var_dump($c,$d);
?>
输出:
dbkuaizi-alpine:/home# php test/demo.php
project
test
string(4) "test"
int(0)
------
sh: ll: not found
string(0) ""
int(127)
exec
执行一个外部程序。
参数说明
exec(string $command[, array &$output = ?, int &$return_var = ?]): string
-
command 要执行的命令 -
output 如果提供了此参数,那么会用执行命令的输出填充此数组,每行输出填充数组的一个元素。需要注意的是 exec()
函数会在数组末尾追加函数,所以在多次调用的情况下,请在exec()
函数调用,对数组使用unset()
进行重置。 -
return_var 命令执行后的返回状态将会被写入到此变量中。
返回值
例子
<?php
$a = exec('ls /home',$b,$c);
var_dump($a,$b,$c);
echo '------'.PHP_EOL;
$a = exec('ls /usr',$b,$c);
var_dump($a,$b,$c);
?>
输出
dbkuaizi-alpine:/home# php test/demo.php
string(4) "test"
array(2) {
[0]=>
string(7) "project"
[1]=>
string(4) "test"
}
int(0)
------
string(5) "share"
array(8) {
[0]=>
string(7) "project"
[1]=>
string(4) "test"
[2]=>
string(3) "bin"
[3]=>
string(3) "lib"
[4]=>
string(7) "libexec"
[5]=>
string(5) "local"
[6]=>
string(4) "sbin"
[7]=>
string(5) "share"
}
int(0)
由于 $output
是追加写入到数组的末尾,所以如果多次调用 一定要在调用之前 unset()
重置这个变量。
passthru
执行外部程序并显示原始输出,输出所执行命令的二进制数据。
诸如执行 pbmplus 之类的可以直接输出图像流的命令,通过设置 Content-type 为 image/gif, 然后调用 pbmplus 程序输出 gif 文件, 就可以从 PHP 脚本中直接输出图像到浏览器。
参数说明
passthru(string $command[, int &$result_code = null]): ?bool
-
command 要执行的命令 -
result_code 若提供此参数,则命令执行返回的状态码将会被记录到此参数中
返回值
成功返回 null,失败返回 false。
实际测试时,成功失败返回的都是 null。若要判断是否执行成功,请使用状态码判断。
例子
<?php
$a = passthru('ls /home',$b);
var_dump($a,$b);
echo '------' . PHP_EOL;
$c = passthru('ls /homec',$d);
var_dump($c,$d)
?>
输出:
dbkuaizi-alpine:/home# php ./test/demo.php
project
test
NULL
int(0)
------
ls: /homec: No such file or directory
NULL
int(1)
dbkuaizi-alpine:/home#
需要特别注意的是,如果是在 Web 方式下执行上述的函数,当外部程序执行耗时大于 PHP 设定的超时时间,则会直接结束进程,不会有任何返回值。
参考文档:https://www.php.net/manual/zh/book.exec.php
笔记作者:两双筷子
博客:www.dbkuaizi.com
原文始发于微信公众号(两双筷子):PHP 程序执行函数
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/78462.html