------------------------------------------------------------------

一、PHP调用外部命令总结                                                       

二、安全问题

三、超时问题

------------------------------------------------------------------

一、PHP调用外部命令总结
在PHP中调用外部命令,可以用,

1>调用专门函数

2>反引号

3>popen()函数打开进程,三种方法来实现。

1>专门函数

php提供4种方法执行系统外部命令:exec()、passthru()、system()、 shell_exec()。
在开始介绍前,先检查下php配置文件php.ini中是有禁止这是个函数。找到 disable_functions,配置如下:

disable_functions =

如果“disable_functions=”后面有接上面四个函数,将其删除。
默认php.ini配置文件中是不禁止你调用执行外部命令的函数的。

 exec()

function exec(string $command,array[optional] $output,int[optional] $return_value)

php代码:

1
2
3
4
5
<?php
echo exec("ls",$file);
echo "</br>";
print_r($file);
?>

执行结果:

test.php
Array( [0] => index.php [1] => test.php)

知识点:
exec
执行系统外部命令时不会输出结果,而是返回结果的最后一行,如果你想得到结果你可以使用第二个参数,让其输出到指定的数组,此数组一个记录代表输出的一行,即如果输出结果有20行,则这个数组就有20条记录,所以如果你需要反复输出调用不同系统外部命令的结果,你最好在输出每一条系统外部命令结果时清空这个数组,以防混乱。第三个参数用来取得命令执行的状态码,通常执行成功都是返回0。

 passthru()

function passthru(string $command,int[optional] $return_value)

代码:

1
2
3
<?php
passthru("ls");
?>

执行结果:

index.phptest.php

知识点:
passthru与system的区别,passthru直接将结果输出到浏览器,不需要使用 echo 或 return 来查看结果,不返回任何值,且其可以输出二进制,比如图像数据。

 system()

function system(string $command,int[optional] $return_value)

代码:

1
2
3
<?php
system("ls /");
?>

执行结果:

binbootcgroupdevetchomeliblost+foundmediamntoptprocrootsbinselinuxsrvsystmpusrvar

知识点:
system和exec的区别在于system在执行系统外部命令时,直接将结果输出到浏览器,不需要使用 echo 或 return 来查看结果,如果执行命令成功则返回true,否则返回false。第二个参数与exec第三个参数含义一样。

 反撇号`和shell_exec()
shell_exec() 函数实际上仅是反撇号 (`) 操作符的变体
代码:

1
2
3
<?php
echo `pwd`;
?>

执行结果:

/var/www/html

2>反引号
原型: 反撇号`(和~在同一个键)执行系统外部命令
说明: 在使用这种方法执行系统外部命令时,要确保shell_exec函数可用,否则是无法使用这种反撇号执行系统外部命令的。
<?php
    echo `dir`;
?>

3>popen()函数打开进程
原型: resource popen ( string $command , string $mode )
说明: 能够和命令进行交互。之前介绍的方法只能简单地执行命令,却不能与命令交互。有时须向命令输入一些东西,如在增加系统用户时,要调用su来把当前用户换到root用户,而su命令必须要在命令行上输入root的密码。这种情况下,用之前提到的方法显然是不行的。
popen( )函数打开一个进程管道来执行给定的命令,返回一个文件句柄,可以对它读和写。返回值和fopen()函数一样,返回一个文件指针。除非使用的是单一的模式打开(读or写),否则必须使用pclose()函数关闭。该指针可以被fgets(),fgetss(),fwrite()调用。出错时,返回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);
?>

二、安全问题

由于PHP基本是用于WEB程序开发的,所以安全性成了人们考虑的一个重要方面。
于是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调用外部命令的更多相关文章

  1. Perl调用外部命令的方式和区别

    主要的方式简述如下:1. system("command");使用该命令将开启一个子进程执行引号中的命令,父进程将等待子进程结束并继续执行下面的代码. 2. exec(" ...

  2. scala调用外部命令

     scala调用外部命令 1.  导入sys.process包 2. 调用方式:" 外部命令 " !     双引号内+外部命令+感叹号 例:     scala调用外部命令工作原 ...

  3. 如何在Python脚本中调用外部命令(就像在linux shell或Windows命令提示符下输入一样)

    如何在Python脚本中调用外部命令(就像在linux shell或Windows命令提示符下输入一样) python标准库中的subprocess可以解决这个问题. from subprocess ...

  4. Perl调用外部命令(其他脚本、系统命令)的方法和区别

    1. `command`; 使用反引号调用外部命令能够捕获其标准输出,并按行返回且每行结束处附带一个回车.反引号中的变量在编译时会被内插为其值.   2. open LIST "ls -l| ...

  5. JDK1.5新特性,基础类库篇,调用外部命令类(ProcessBuilder)用法

    一. 背景 ProcessBuilder类是用来创建操作系统进程的.与Runtime.exec相比,它提供了更加方便的方法以创建子进程. 每个ProcessBuilder实例管理着一个进程属性的集合. ...

  6. PHP中调用外部命令的方法

    在PHP中调用外部命令,可以用如下三种方法来实现: 方法一:用PHP提供的专门函数(四个): PHP提供4个专门的执行外部命令的函数:exec(), system(), passthru(), she ...

  7. Python 调用外部命令

    python 可以使用 os 模块来调用外部的 Linux Shell 命令,常用的方法如下: os.system():结果输出在终端上,捕获不到os.popen() : 结果返回一个对象,即标准输出 ...

  8. linux sh 脚本调用外部命令

    参考:http://blog.csdn.net/lhb_blog/article/details/22083649 ------------------------------------------ ...

  9. C# cmd调用外部命令

    void test2() { Process process = new Process(); //C:\\Users\\Administrator\\Desktop\\ffmpeg\\bin\\ff ...

随机推荐

  1. vue 的准备项目架构环境配置

    一.环境搭建 中国镜像 composer config repo.packagist composer https://packagist.phpcomposer.com 命令 composer in ...

  2. Servlet开篇

    Servlet开篇 前面我已经说过好多遍了,如何学习好一个东西其实就是2个问题: 1,这个东西是干嘛的?为什么要玩这个东西? 2,怎么样就玩好这个东西了?具体的应该玩这个东西的什么? 其实现在对于我来 ...

  3. JAVA中实现让程序等待一段时间的方法

    JAVA中想让代码等待一段时间再继续执行,可以通过让当前线程睡眠一段时间的方式. 方法一:通过线程的sleep方法. Thread.currentThread().sleep(1000); 在需要程序 ...

  4. MySQL备份利器-xtrabackup的介绍和原理(附脑图)

    标签(linux): mysql-xtrabackup 笔者Q:972581034 交流群:605799367.有任何疑问可与笔者或加群交流 xtrabackup是Percona公司针对mysql数据 ...

  5. IOS 疯狂基础之 页面间跳转

    常用的就两种 一种通过导航,一种直接跳 第一种 直接跳转 思路大致就是new一个目的页面,然后设置下页面跳转动画 中间还可以做点目的页面的数据初始化: ValueInputView *valueVie ...

  6. 2017-12-30-如何彻底清除现存GIT仓库的大量提交历史

    layout: post title: 2017-12-30-如何彻底清除现存GIT仓库的大量提交历史 key: 20171230 tags: GIT 版本管理 问答 modify_date: 201 ...

  7. Mysql编译安装及优化

    采取编译安装的方法,其好处为:编译安装与平台无关,安装的MySQL目录独立,维护起来方便,而且拥有更好的性能. 环境:CentOS release 6.9 (Final)  x86_64 1)下载my ...

  8. 正则匹配url中的query参数信息

    var url = 'name=xiaoming&age=10&school=xinhua'; var reg = /([^&=]+)=?([^&]*)/g;

  9. c#控制WPF程序自动登录(Automation方式实现)

    说明:winForm窗体,可以通过win32接口dll的findWindow之类的函数来实现查找winform窗口,mfc窗口等. 但是wpf却是不实用这些,可以靠automation方式来进行操作. ...

  10. 删除一个目录及其子目录下的所有.svn文件

    今天建立svn,加入代码,发现这些个文件夹中竟然已经有.svn文件夹,也就是它以前使用过svn, 这下就有点麻烦,在全新的svn里,这些.svn需要删除,又不可能一个一个手工去删除 网上翻了一下,发现 ...