当前位置:  开发笔记 > 编程语言 > 正文

PHP exec()vs system()vs passthru()

如何解决《PHPexec()vssystem()vspassthru()》经验,为你挑选了5个好方法。

有什么区别?

每个功能都有特定的情况或原因吗?如果是的话,你能举一些这些情况的例子吗?

PHP.net说它们用于执行外部程序.参见参考 从我看到的例子中,我没有看到任何明显的区别.

如果我只是简单地运行一个脚本(bash或python),你建议我使用哪个函数?



1> Kalium..:

他们的目的略有不同.

exec() 用于调用系统命令,也许是自己处理输出.

system() 用于执行系统命令并立即显示输出 - 可能是文本.

passthru() 用于执行您希望原始返回的系统命令 - 可能是二进制文件.

无论如何,我建议你不要使用它们中的任何一个.它们都产生高度不可移植的代码.


有时必须牺牲可移植性来实现功能.有些东西PHP不能很好地完成.
@Christian`izkaata @ izein:〜$ dir -bash:dir:command not found` - FreeBSD
@Kalium:你能详细说明你的陈述吗?只是陈述一些模糊的百分比统计数据并不能说服我.我相信使用系统调用来执行脚本是完全没问题的,只要整个应用程序不依赖于后端的一堆脚本.
恩,什么?它是如何不可移植的?例如,`dir`适用于所有操作系统.这并不是不可取的,它只是需要一些努力使其便携.-1这个愚蠢的概念.
另外,只要你避免使用`exec`,`system`,`passthru`,认为PHP是可移植的,这是一种谬论**.PHP代码依赖于它运行的环境,许多安全漏洞都是由于没有考虑到这一点.这是一个简单的例子:http://stackoverflow.com/questions/3003145/how-to-get-the-client-ip-address-in-php#comment50230065_3003233
@OZ_我遇到了我不得不做非常昂贵的计算的情况.没有PHP模块可用于此.我编写了自己的C程序,并使用passthru()调用它.有时可移植性可能不如其他东西重要.取决于该项目.
"非常不可移植"的代码,以及"更容易受代码注入攻击"的代码.有时这是必要的,但如果可能的话,最好用PHP执行任务.
@Kalium"...... 95%的人都想使用shell调用,原因都是错误的......"我认为这种方法非常主观,你是说所有程序员,devops,系统管理员应该以同样的方式思考,同样的想法在同一条道路上?自由在哪里?我认为没有"错误"的方法,而是有"更好"的方法来处理每个具体的问题.
仅仅因为某些东西不便携,就不会错.例如,我需要一种方法来运行wget来通过Web界面制作网站的静态副本..如果我无法运行程序,这可能会非常困难.
@Frank Crook*有些东西PHP不能很好* - 这就是为什么我们有PHP和API的模块.使用系统调用是古老的方式,使用API​​更加文明.
@Kalium,在许多情况下,当PHP充当其他应用程序的接口时,会使用系统命令.例如,[pentest-tools](https://goo.gl/jorRi0)是一个webapp,为nmap,nessus,nikto等知名安全工具提供界面.用PHP重写这些应用程序**有问题**,不仅因为需要大量的时间,而且因为他们不会以完全相同的方式行事.即使没有错误,重写的应用程序也不会与原始应用程序完全相同,这使诊断成为一个令人头痛的问题.
并非每个人的项目都要求他们在多个操作系统上执行.我不在乎我的PHP是否在Windows下运行,我们控制环境而我们不会将代码提供给其他人使用.
@bLee在实际使用中,我通常会看到系统调用用于执行ls,cp,mv和zip调用之类的小事情,而不是像脚本调用那样真正证明它的任何事情.
通过*"所有操作系统"*,我可能会意外地遗漏了FreeBSD.抱歉.**:)**
@Christian它也不在OS X中.:)

2> Dinesh Saini..:

从绘制 http://php.net/ && Chipmunkninja:

该系统()函数

PHP中的系统函数接受一个带有要执行的命令的字符串参数以及您希望传递给该命令的任何参数.此函数执行指定的命令,并将任何结果文本转储到输出流(Web服务器情况下的HTTP输出,或者如果您将PHP作为命令行工具运行,则控制台).如果它发出文本输出,则返回此函数是程序的最后一行输出.

在EXEC()函数

系统功能非常有用且功能强大,但其中一个最大的问题是程序中的所有结果文本都直接进入输出流.在某些情况下,您可能希望格式化生成的文本并以不同的方式显示它,或者根本不显示它.

为此,PHP中的exec函数完全适应.它不是自动将正在执行的程序生成的所有文本转储到输出流,而是让您有机会将此文本放在第二个参数返回的数组中:

该了shell_exec()函数

到目前为止,我们执行的大多数程序或多或少都是真正的程序1.但是,Windows和Unix用户运行的环境实际上比这更丰富.Windows用户可以选择使用Windows命令提示符程序cmd.exe此程序称为命令shell.

的通路()函数

PHP提供的一个令人着迷的功能类似于我们迄今为止看到的功能是passthru功能.与其他函数一样,此函数执行您告诉它的程序.但是,它会立即将此程序的原始输出发送到PHP当前正在使用的输出流(即Web服务器方案中的HTTP,或PHP命令行版本中的shell).

的proc_open()函数和POPEN() 函数

proc_open()类似于popen(),但提供了对程序执行的更大程度的控制.cmd是shell要执行的命令.descriptorspec是一个索引数组,其中键表示描述符编号,值表示PHP将该描述符传递给子进程的方式.管道将被设置为文件指针的索引数组,这些数组对应于PHP创建的任何管道的末尾.返回值是表示进程的资源; 你应该在完成它后使用proc_close()释放它.


您应该提到您已直接从[ChipmunkNinja](http://chipmunkninja.com/Program-Execution-in-PHP%3A-exec-m@)复制了答案.
@TachyonVortex幸运的是,他确实逐字复制了答案,因为ChipmunkNinja不再存在.
shell_exec执行速度比其他备用速度快.
popen和proc_open怎么样?

3> orrd..:

之前的回答似乎都有点混乱或不完整,所以这里有一个差异表...

+----------------+-----------------+----------------+----------------+
|    Command     | Displays Output | Can Get Output | Gets Exit Code |
+----------------+-----------------+----------------+----------------+
| system()       | Yes (as text)   | Last line only | Yes            |
| passthru()     | Yes (raw)       | No             | Yes            |
| exec()         | No              | Yes (array)    | Yes            |
| shell_exec()   | No              | Yes (string)   | No             |
| backticks (``) | No              | Yes (string)   | No             |
+----------------+-----------------+----------------+----------------+

"显示输出"表示它将输出流式传输到浏览器(如果从命令行运行,则输出命令行输出).

"可以获取输出"意味着您可以获取命令的输出并将其分配给PHP变量.

"退出代码"是命令返回的特殊值(也称为"返回状态").零通常意味着它是成功的,其他值通常是错误代码.

其他需要注意的事项:

shell_exec()和反引号运算符执行相同的操作.

还有proc_open()和popen(),它们允许您使用执行命令以交互方式读/写流.

如果您还想捕获/显示错误消息,请在命令字符串中添加"2>&1".

使用escapeshellcmd()来转义可能包含问题字符的命令参数.

如果将$ output变量传递给exec()来存储输出,如果$ output不为空,它会将新输出附加到它.所以你可能需要先取消设置($ output).



4> Cody Caughla..:

它实际上归结为您希望如何处理命令可能返回的输出以及您是否希望PHP脚本等待被调用程序完成.

exec 执行命令并将输出传递给调用者(或在可选变量中返回).

passthru类似于exec()它执行命令的功能.当Unix命令的输出是需要直接传递回浏览器的二进制数据时,应使用此函数代替exec()system()输入.

system 执行外部程序并显示输出,但只显示最后一行.

如果您需要执行命令并将命令中的所有数据直接传回而没有任何干扰,请使用该passthru()功能.



5> Matt..:

如果您从命令行运行PHP脚本,则passthru()有一个很大的好处.它将允许您执行脚本/程序,如vim,dialog等,让这些程序处理控制并仅在完成后返回脚本.

如果您使用system()exec()执行这些脚本/程序,它将无法正常工作.

疑难杂症:出于某种原因,你不能执行lesspassthru()在PHP.

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有