PHP 执行外部命令函数:exec()、system()、passthru()、shell |
您所在的位置:网站首页 › exec函数开启 › PHP 执行外部命令函数:exec()、system()、passthru()、shell |
PHP内置函数,提供了4种方法执行系统外部命令: exec()、system()、passthru()、 shell_exec()
查看命令函数配置 在开始介绍前,先检查下php配置文件php.ini中是有禁止这是个函数 vim /etc/php.ini 或 vim /usr/local/php/lib/php.ini php.ini 默认配置文件中是不禁止你调用执行外部命令的函数的。 找到 disable_functions,正常开启的配置为 disable_functions = ,具体如下: 1 2 3 4 5 ; This directive allows you to disable certain functions for security reasons. ; It receives a comma-delimited list of function names. This directive is ; *NOT* affected by whether Safe Mode is turned On or Off. ; http://php.net/disable-functions disable_functions = 如果“disable_functions=”后面有接上面四个函数,将其删除,并重启 httpd 或 php-fpm
exec() 原型:string exec ( string $command [, array &$output [, int &$return_var ]] ) 说明: 第一个参数, $command 是要执行的命令,例如: "ls -l" 第二个参数,$output 是command执行输出的结果,以数组格式存储 第三个参数,$return_var,用于保存command执行状态,0 - 成功,非零 - 失败 返回值,为command执行结果的最后一行
示例: 1 2 3 4 5 6 7 8 9 10 11 12 // exec $retval = null; $res = null; $res_array = array();
$cmd = "/usr/bin/curl -k --head 'https://mimvp.com'"; $res = exec($cmd, $res_array, $retval);
echo " exec result:"; var_dump($retval); // 0 (返回的状态, 0 - 成功, 非零 - 失败) var_dump($res); // '' var_dump($res_array); // 返回结果数组 运行结果: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 exec result: /Users/homer/mimvp_site/api/header2.php:55:int 0 /Users/homer/mimvp_site/api/header2.php:56:string '' (length=0) /Users/homer/mimvp_site/api/header2.php:57: array (size=9) 0 => string 'HTTP/2 200' (length=10) 1 => string 'server: nginx' (length=13) 2 => string 'date: Tue, 26 Dec 2017 01:52:11 GMT' (length=35) 3 => string 'content-type: text/html; charset=UTF-8' (length=38) 4 => string 'vary: Accept-Encoding' (length=21) 5 => string 'vary: Accept-Encoding' (length=21) 6 => string 'vary: mimvp-home-bj2' (length=20) 7 => string 'vary: mimvp-homes-bj2' (length=21) 8 => string '' (length=0) 从结果看 1)第二行结果 $retval 为状态 0 ,表示 cmd 命令执行成功 2)第三行结果 $res 为空字符串 '',表示 cmd 命令执行返回结果的最后一行,见 $res_array 数组最后一行(第八行)为空 3)第五行结果 $res_array 保存了完整的 cmd 命令执行结果,说明第二个参数保存 exec 执行结果 知识点: exec 执行系统外部命令时,只返回结果的最后一行,如果想得到完整的执行结果,需要使用第二个参数,让其输出到指定的数组,此数组一个记录代表输出的一行,即如果输出结果有20行,则这个数组就有20条记录。所以,如果你需要反复输出调用不同系统外部命令的结果,最好在输出每一条系统外部命令结果时清空这个数组 $res_array = array(),以防混乱。第三个参数用来取得命令执行的状态码,通常执行成功都是返回0
system() 原型:string system ( string $command [, int &$return_var ] ) 说明: 第一个参数, $command 是要执行的命令,例如: "ls -l" 第二个参数,$return_var,用于保存command执行状态,0 - 成功,非零 - 失败 返回值,为command执行结果的最后一行(system 和 exec 类似),失败返回 FALSE
示例: 1 2 3 4 5 6 7 8 9 10 // system $retval = null; $res = null;
$cmd = "/usr/bin/curl -k --head 'https://mimvp.com'"; $res = system($cmd, $retval);
echo " system result:"; var_dump($retval); // 0 (返回的状态, 0 - 成功, 非零 - 失败) var_dump($res); // '' 运行结果: 1 2 3 4 5 cmd : /usr/bin/curl -k --head 'https://mimvp.com'HTTP/2 200 server: nginx date: Tue, 26 Dec 2017 01:52:11 GMT content-type: text/html; charset=UTF-8 vary: Accept-Encoding vary: Accept-Encoding vary: mimvp-home-bj2 vary: mimvp-homes-bj2
system result: /Users/homer/mimvp_site/api/header2.php:41:int 0 /Users/homer/mimvp_site/api/header2.php:42:string '' (length=0) 从结果看 1)第一行结果,打印输出命令时,直接在屏幕上打印了 sytem 执行命令的返回结果,没法保存,因此system用于不保存结果的场景 2)第三行结果 $retval 为状态 0 ,表示 cmd 命令执行成功 3)第四行结果 $res 为空字符串 '',表示 cmd 命令执行返回结果的最后一行,其结果为空
passthru() 原型:void passthru ( string $command [, int &$return_var ] ) passthru 和 system 基本是一样的,结果不保存,直接输出在屏幕上,两者仅是返回值不同 1)system 是返回结果的最后一行,类型为 string 2)passthru 不返回结果,类型为 void 说明: 第一个参数, $command 是要执行的命令,例如: "ls -l" 第二个参数,$return_var,用于保存command执行状态,0 - 成功,非零 - 失败 返回值,为空 void
示例: 1 2 3 4 5 6 7 8 9 10 // passthru $retval = null; $res = null;
$cmd = "/usr/bin/curl -k --head 'https://mimvp.com'"; $res = passthru($cmd, $retval);
echo " passthru result:"; var_dump($retval); // 0 (返回的状态, 0 - 成功, 非零 - 失败) var_dump($res); // '' 运行结果: 1 2 3 4 5 HTTP/2 200 server: nginx date: Tue, 26 Dec 2017 01:52:11 GMT content-type: text/html; charset=UTF-8 vary: Accept-Encoding vary: Accept-Encoding vary: mimvp-home-bj2 vary: mimvp-homes-bj2
passthru result: /Users/homer/mimvp_site/api/header2.php:48:int 0 /Users/homer/mimvp_site/api/header2.php:49:null 从结果看 1)第一行结果,打印输出命令时,直接在屏幕上打印了 sytem 执行命令的返回结果,没法保存,跟system类似 2)第三行结果 $retval 为状态 0 ,表示 cmd 命令执行成功 3)第四行结果 $res 为空字符串为null,即不返回结果 void
shell_exec() 原型:string shell_exec ( string $cmd ) shell_exec 与 exec 类似,只是没有返回状态,其状态和cmd执行结果,都以结果返回 1)如果执行cmd成功,则返回执行结果 2)如果执行cmd失败,则返回 NULL 说明: 第一个参数, $command 是要执行的命令,例如: "ls -l" 返回值,为command执行结果,如果失败则返回 NULL
示例: 1 2 3 4 5 6 7 8 // shell_exec $res = null;
$cmd = "/usr/bin/curl -k --head 'https://mimvp.com'"; $res = shell_exec($cmd);
echo " shell_exec result:"; var_dump($res); // 返回执行结果,或失败返回NULL 运行结果: 1 2 3 4 5 6 7 8 9 10 11 shell_exec result: /Users/homer/mimvp_site/api/header2.php:84:string 'HTTP/2 200 server: nginx date: Tue, 26 Dec 2017 01:52:11 GMT content-type: text/html; charset=UTF-8 vary: Accept-Encoding vary: Accept-Encoding vary: mimvp-home-bj2 vary: mimvp-homes-bj2
' (length=198) 从结果看 执行cmd输出结果,以字符串返回给了 $res ,并保留了换行
popen() 原型:resource popen ( string $command , string $mode ) 通过pipe管道执行shell命令,也是一种常见的方式,python也有类似的命令 说明: 第一个参数, $command 是要执行的命令,例如: "ls -l" 第二个参数,$mode 是指定读写、执行等操作类型,如 'r', 'w', 'x' 返回值,是一个资源句柄,可用来具体的操作命令的资源,一般配合 fgets()、fgetss()、fwrite() 使用
示例: 1 2 3 4 5 6 // popen $handle = popen($cmd, 'r'); $res = fread($handle, 8888); echo " popen result:"; var_dump($res); pclose($handle); // 资源句柄执行完后,一定要记得关闭 运行结果: 1 2 3 4 5 6 7 8 9 10 11 popen result: /Users/homer/mimvp_site/api/header2.php:90:string 'HTTP/2 200 server: nginx date: Tue, 26 Dec 2017 02:57:55 GMT content-type: text/html; charset=UTF-8 vary: Accept-Encoding vary: Accept-Encoding vary: mimvp-home-bj2 vary: mimvp-homes-bj2
' (length=198)
PHP 执行命令函数的应用实例 PHP 执行外部命令函数 exec()、system()、passthru()、shell_exec() 不是花瓶,一切皆因需求而生 例如,PHP 前端执行直接从shell获取一些查询结果,充分利用强大的shell命令,如 curl、wget、whois 等
PHP 内置函数 get_headers() 用于获取服务器端返回的头信息,如果失败了可以通过 curl --head 来获取 实例代码,封装如下 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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 // 获取server返回头信息 function get_response_header($url='https://mimvp.com') { $res_headers = array();
try { $res_headers = get_headers($url, 1); // 0 - 不格式化; 1 - 格式化 if($res_headers == false) { // 返回结果失败
$retval = null; $res = null; $res_array = array(); $cmd = sprintf("/usr/bin/curl -k --head '%s'", $url); echo ' cmd : ' . $cmd;
// exec $res = exec($cmd, $res_array, $retval); echo " exec result:"; var_dump($retval); // 0 (返回的状态, 0 - 成功, 非零 - 失败) var_dump($res); // '' var_dump($res_array); // 返回结果数组
$idx = 0; foreach($res_array as $line) { // $res_array 转成 $res_headers $line = str_replace(":", ":", trim($line));
if($idx == 0 && $line != "") { // 处理第一行的状态 $res_headers[0] = $line; } if(strstr($line, ":") != "") { $key = trim(explode(":", $line)[0]); $val = trim(explode(":", $line)[1]); $res_headers[$key] = $val; } else if($idx >= 2 && $line != "") { $res_headers[$idx] = $line; } $idx += 1; } } } catch (Exception $e) { var_dump($e); }
var_dump($res_headers); return $res_headers; } 运行结果 1)正常时,执行 get_headers() ,返回结果如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 /Users/homer/Downloads/myCode/workspace/navi_client/api/header2.php:67: array (size=6) 0 => string 'HTTP/1.1 200 OK' (length=15) 'Server' => string 'nginx' (length=5) 'Date' => string 'Tue, 26 Dec 2017 02:38:59 GMT' (length=29) 'Content-Type' => string 'text/html; charset=UTF-8' (length=24) 'Connection' => string 'close' (length=5) 'Vary' => array (size=4) 0 => string 'Accept-Encoding' (length=15) 1 => string 'Accept-Encoding' (length=15) 2 => string 'mimvp-home-bj2' (length=14) 3 => string 'mimvp-homes-bj2' (length=15)
2)失败时,执行 curl --head ,返回结果如下: 1 2 3 4 5 6 7 /Users/homer/Downloads/myCode/workspace/navi_client/api/header2.php:67: array (size=5) 0 => string 'HTTP/2 200' (length=10) 'server' => string 'nginx' (length=5) 'date' => string 'Tue, 26 Dec 2017 02' (length=19) 'content-type' => string 'text/html; charset=UTF-8' (length=24) 'vary' => string 'mimvp-homes-bj2' (length=15) 在 shell 执行cmd命令,查看其结果 1 2 3 4 5 6 7 8 9 10 $ /usr/bin/curl -k --head 'https://mimvp.com' HTTP/1.1 200 OK Server: nginx Date: Tue, 26 Dec 2017 02:45:52 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive Vary: Accept-Encoding Vary: Accept-Encoding Vary: mimvp-home-bj2 Vary: mimvp-homes-bj2 可见,curl --head 基本补充了 get_headers 执行失败时获取服务器端头信息的功能 还有一点瑕疵就是 Vary 变量数组处理的不完美,完整代码量大,在此不给出了,请自行判断实现之
|
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |