热烈祝贺台州朗动科技的站长论坛隆重上线!(2012-05-28)    热烈庆祝伟大的祖国60周年生日 点击进来我们一起为她祝福吧(2009-09-26)    站长论坛禁止发布广告,一经发现立即删除。谢谢各位合作!.(2009-08-08)    热烈祝贺台州网址导航全面升级,全新版本上线!希望各位一如既往地支持台州网址导航的发展.(2009-03-28)    台州站长论坛恭祝各位新年快乐,牛年行大运!(2009-01-24)    台州Link正式更名为台州网址导航,专业做以台州网址为主的网址导航!(2008-05-23)    热烈祝贺台州Link资讯改名为中国站长资讯!希望在以后日子里得到大家的大力支持和帮助!(2008-04-10)    热烈祝贺台州Link论坛改名为台州站长论坛!希望大家继续支持和鼓励!(2008-04-10)    台州站长论坛原[社会琐碎]版块更名为[生活百科]版块!(2007-09-05)    特此通知:新台州站长论坛的数据信息全部升级成功!">特此通知:新台州站长论坛的数据信息全部升级成功!(2007-09-01)    台州站长论坛对未通过验证的会员进行合理的清除,请您谅解(2007-08-30)    台州网址导航|上网导航诚邀世界各地的网站友情链接和友谊联盟,共同引领网站导航、前进!(2007-08-30)    禁止发广告之类的帖,已发现立即删除!(2007-08-30)    希望各位上传与下载有用资源和最新信息(2007-08-30)    热烈祝贺台州站长论坛全面升级成功,全新上线!(2007-08-30)    
便民网址导航,轻松网上冲浪。
台州维博网络专业开发网站门户平台系统
您当前的位置: 首页 » PHP/Perl编程 » 如何利用内置PHP灵活性执行外部程序

如何利用内置PHP灵活性执行外部程序

论坛链接
  • 如何利用内置PHP灵活性执行外部程序
  • 发布时间:2007-10-04 16:55:51    浏览数:5257    发布者:tznktg    设置字体【   
没有人会怀疑,即使是最苛刻的批评家也不会怀疑PHP是多功能的:在最近的一次统计中,该语言有1,500多个内置函数和超过150个新增的扩展插件。但是,聪慧的PHP的创作者知道这些还不足以满足每一个人的要求,所以他们有额外添加了一定的灵活度――允许开发者从PHP内部启动他们自己的外部程序,并将所得到的输出再插入PHP应用程序中――所有的一切都不费吹灰之力!

本文将向你介绍一些允许你启动外部程序的PHP函数,向你说明怎样获得输出或在你的PHP脚本中使用结果代码,并提醒你注意过程中潜在的弱点。

反引号运算符

如果你已经在*NIX中用过Bash shell,那么你一定已经比较熟悉反引号运算符(`),它可以用来在Bash脚本内部运行一个外部程序。PHP也正是采用了相同的技术:在PHP脚本中,简单地将外部程序的命令行放入反引号中,PHP将会在到达该行代码时启动这个外部程序。列表A向你显示了该怎么做。

列表A

<?php
`ls -l`;
?>

当然,就其本身而言,是没有什么作用的;多数情况下,你会想要将外部程序的输出引入到你的PHP脚本中进行进一步的处理。幸运的是,这也很简单――你要做的就是将反引号中所引的代码当做一个规则的PHP变量,然后用函数echo()或print()将其显示出来。(列表B)

列表B
<?php
echo "Current date and time is: " . `date`;
?>

在本文里,PHP将获得系统命令的输出,然后用echo()将它内插入字符串中。输出如下:

Current date and time is: Wed Jun 21 04:27:01 CDT 2006

如果你愿意的话,你也可以获得并储存一个外部命令的输出,只需简单地将反引号中所引的命令赋值于一个变量就行了。(列表C)

列表C
<?php
$date = `date`;
echo "Current date and time is: $date";
?>

以下是输入:

Current date and time is: Wed Jun 21 04:27:01 CDT 2006

函数exec()和passthru()

当PHP 的安全模式被激活时,反引号运算符就不可用了,这样如果在一个对PHP配置提供有限控制的共享主机上运行你的应用程序的话,就会出现问题。在这种情况下,你没有其它选择,只能采用两个PHP的内置函数exec()和passthru()了,它们能够提供相似的功能。

函数exec()接受单个的包含了要执行命令的必要参数,运行它,然后会返回输出的最后一行。(列表D)

列表D
<?php
echo exec('ls -l');
?>

输出是:

drwxr-xr-x 5 user cust 512 Jan 27 2005 vhost

大多数情况下,只检索命令的最后一行是不够的,这也是为什么exec()同时提供了两个备选的参数。第一个是一个数组,其中填充着命令得到的输出的每一行;第二个是一个保存命令返回的状态代码的变量。

列表E向你展示了一个例子。

列表E
<?php
$data = array(); // define array

exec('ls -l', $data, $ret); // execute command, output is array

echo "<pre>";
if ($ret == 0) { // check status code. if successful
foreach ($data as $line) { // process array line by line
echo "$line \n";
}
} else {
echo "Error in command"; // if unsuccessful display error
}
echo "</pre>";
?>

这似乎很复杂,但是实际上非常简单。首先,定义一个空数组$data,调用exec()命令获得一个目录列表。命令返回的代码显示了它是否成功,然后将其储存在$ret中,列表的输出(如果有的话)储存在前面定义的数组$data中。接下来,返回的代码被检验,如果为0(表示成功了),再用一个foreach()循环来处理数组,并显示目录列表。如果返回的代码不为0的话,可能会认为发生了一个错误;跳过数组处理,而显示一个错误信息。

列表F向你显示了输出。



列表F
total 90
-rw-r--r-- 1 user cust 611 Jul 17 2004 CHANGE
drwxr-xr-x 2 user cust 512 Jul 27 2004 cgi
drwxr-xr-x 5 user cust 512 Jan 27 2005 vhost

函数passthru()和exec()类似,除了一点,就是它在被调用时直接将原始的输出返回到浏览器。通常,这只有在你的外部命令的输出是原始二元数据,需要直接输入到解码器中的时候才有用――例如,一个音频流或图象。列表G举例说明了passthru()是如何起作用的。.

列表G
<?php
header("Content-Type: audio/wav"); // send MIME headers
passthru("cat hello.wav"); // send binary data
?>

潜在的弱点

通过PHP脚本执行外部命令始终是一个冒险的建议。如果你的应该程序允许用户输入,那么就会始终存在用户捉弄系统,执行有害命令的危险。为了避免这一点,可以有两种选择:

1.避开命令字符串

PHP提供了escapeshellcmd()和escapeshellarg()函数,这两个函数会利用引号和反斜线“清除”命令字符串和变量。在将任意的用户输入exec()、passthru()或反引号运算符之前,对它们运行这些命令是一个好办法。(列表H)

列表H


<?php
$cmd = "ls / -als & rm -rf /";
exec(escapeshellcmd($cmd));
?>

2.利用安全模式

另一个选择就是激活PHP的“安全模式”,来限制什么样的用户可以利用exec()和passthru()。反引号运算符在安全模式下是不可用的,而exec()和passthru()只能用来执行位于前面所定义的“安全”目录中的命令。这样就对这些命令提供了清晰的界限,并减少了与在脚本中使用它们相关的总风险。

但愿你现在应该对怎样从PHP内部启动外部程序有了一个清晰的看法,也对怎么样在使用这些性能时,保护你的应用程序免受黑客攻击有所了解。继续自己尝试它们吧……编程快乐!
娱乐休闲专区A 影视预告B 音乐咖啡C 英语阶梯D 生活百科
网页编程专区E AMPZF HTMLG CSSH JSI ASPJ PHPK JSPL MySQLM AJAX
Linux技术区 N 系统管理O 服务器架设P 网络/硬件Q 编程序开发R 内核/嵌入
管理中心专区S 发布网址T 版主议事U 事务处理