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

问题描述 投票:294回答:5

有什么区别?

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

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

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

php command exec
5个回答
180
投票

他们的目的略有不同。

  • exec()用于调用系统命令,并且可能自己处理输出。
  • system()用于执行系统命令并立即显示输出 - 可能是文本。
  • passthru()用于执行一个系统命令,你希望原始返回 - 可能是二进制文件。

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


120
投票

http://php.net/ && Chipmunkninja得出:

system()功能

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

exec()功能

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

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

shell_exec()功能

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

passthru()功能

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

proc_open()功能和popen()功能

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


81
投票

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

+----------------+-----------------+----------------+----------------+
|    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)。

18
投票

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

  • exec执行命令并将输出传递给调用者(或将其返回到可选变量中)。
  • passthru类似于exec()函数,因为它执行命令。当Unix命令的输出是需要直接传递回浏览器的二进制数据时,应该使用此函数代替exec()system()
  • system执行外部程序并显示输出,但只显示最后一行。

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


6
投票

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

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

问:由于某种原因,你不能用PHP中的less执行passthru()

© www.soinside.com 2019 - 2024. All rights reserved.