system/exec 函数:
这两个函数会利用/bin/sh 指定的shell来执行指定的命令,所以,指定的命令实际上不仅可以包含可以执行的命令和参数,还可以是对应shell的内置命令以及shell支持的控制结构。
缺点: 无法区分标准输出与标准错误
注意: 这两个函数执行的外部命令默认继承了php进程的标准输入、标准输出和标准错误,你可以通过返回值得到进程的标准输出,但是标准错误却悄悄地流进了php进程定义的标准错误输出里面去了;更加隐晦的是,对于php-fpm进程来讲,该外部进程也默认listen(继承来的)了php-fpm监听的端口,但是肯定不会去处理php-fpm请求,一般情况下不会有问题,特殊情况下回让你莫名其妙
pcntl_exec 函数:
该函数会取代当前执行的进程空间,而且是不会再回到当前进程空间,可能你很少会用到该函数,但是,当你确实需要该函数的时候,却又是没有其他函数可以替代的,如:
# php -d error_log="" -r 'pcntl_exec("/bin/sleep", array(1));echo 2;'
1
# php -d error_log="" -r 'pcntl_exec("/bin/sleep", array(1));echo 2;'
echo 2 是不可能被执行到的
注意: pcntl_exec不同于其他函数,并不会使用shell来执行指定的命令,而且指定的命令需要是要执行的可执行文件的全路径
proc_open 函数:
这个是我最喜欢的函数:
可以通过proc_close得到外部进程的返回值
可以定义外部进程的标准输入、标准输出、标准错误,并且可以区分外部进程的标准输出和标准错误
一定程度上还可以实现并行执行多个外部命令
proc_open 示例:
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a file to write to
);
$cwd = '/tmp';
$env = array('some_option' => 'aeiou');
$process = proc_open('ssh -i /home/phpor/.ssh/id_rsa phpor@localhost ', $descriptorspec, $pipes, $cwd, $env);
if (is_resource($process)) {
// $pipes now looks like this:
// 0 => writeable handle connected to child stdin
// 1 => readable handle connected to child stdout
// Any error output will be appended to /tmp/error-output.txt
fwrite($pipes[0], $argv[1]);
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
echo stream_get_contents($pipes[2]);
fclose($pipes[2]);
// It is important that you close any pipes before calling
// proc_close in order to avoid a deadlock
$return_value = proc_close($process);
echo "command returned $return_value\n";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$descriptorspec=array(
0=>array("pipe","r"),// stdin is a pipe that the child will read from
1=>array("pipe","w"),// stdout is a pipe that the child will write to
2=>array("pipe","w")// stderr is a file to write to
);
$cwd='/tmp';
$env=array('some_option'=>'aeiou');
$process=proc_open('ssh -i /home/phpor/.ssh/id_rsa phpor@localhost ',$descriptorspec,$pipes,$cwd,$env);
if(is_resource($process)){
// $pipes now looks like this:
// 0 => writeable handle connected to child stdin
// 1 => readable handle connected to child stdout
// Any error output will be appended to /tmp/error-output.txt
fwrite($pipes[0],$argv[1]);
fclose($pipes[0]);
echostream_get_contents($pipes[1]);
fclose($pipes[1]);
echostream_get_contents($pipes[2]);
fclose($pipes[2]);
// It is important that you close any pipes before calling
// proc_close in order to avoid a deadlock
$return_value=proc_close($process);
echo"command returned $return_value\n";
}