【问题标题】:PHP exec() vs system() vs passthru()PHP exec() vs system() vs passthru()
【发布时间】:2010-10-18 11:37:31
【问题描述】:

有什么区别?

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

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

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

【问题讨论】:

  • 还有proc_open()popen(),它们都允许对生成的进程进行更高程度的控制。

标签: php command exec


【解决方案1】:

它们的用途略有不同。

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

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

【讨论】:

  • 有时必须牺牲可移植性来换取功能。有些事情是 PHP 做不到的。
  • @Kalium:你能详细说明你的陈述吗?只是陈述一些模糊的百分比统计数据并不能说服我。我相信使用系统调用来执行脚本是完全可以的,只要整个应用程序不依赖后端的一堆脚本。
  • @Christian izkata@izein:~$ dir -bash: dir: command not found - FreeBSD
  • @OZ_ 我遇到了必须进行非常昂贵的计算的情况。没有可用的 PHP 模块。我编写了自己的 C 程序并使用 passthru() 调用它。有时可移植性可能不如其他事情重要。取决于项目。
  • 此外,如果您避免使用execsystempassthru,认为 PHP 是可移植的,这是一个谬误。 PHP 代码依赖于它运行的环境,许多安全漏洞都是由于没有考虑到这一点。这是一个简单的例子:stackoverflow.com/questions/3003145/…
【解决方案2】:

取自http://php.net/ && Chipmunkninja:

system() 函数

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

exec() 函数

系统功能相当实用且强大,但其中之一 最大的问题是程序产生的所有文本 直接进入输出流。在某些情况下,您 可能想格式化生成的文本并以某种形式显示 不同的方式,或者根本不显示它。

为此,完美适配了 PHP 中的 exec 函数。代替 自动转储正在执行的程序生成的所有文本 到输出流,它使您有机会将此文本放入 函数第二个参数中返回的数组:

shell_exec() 函数

到目前为止,我们执行的大多数程序都是 或更少,真正的程序1。但是,Windows 和 Unix用户的操作其实比这丰富得多。 Windows 用户 可以选择使用 Windows 命令提示符程序 cmd.exe 这个程序被称为命令外壳。

passthru() 函数

PHP 提供的一个令人着迷的功能与我们所拥有的功能相似 到目前为止看到的是 passthru 功能。这个函数和其他函数一样, 执行你告诉它的程序。然而,它接着进行 立即将此程序的原始输出发送到输出流 PHP 当前正在使用哪个(即 Web 服务器中的 HTTP 场景,或 PHP 命令行版本中的 shell)。

proc_open() 函数和popen() 功能

proc_open() 类似于 popen() 但提供了更大的程度 对程序执行的控制。 cmd 是要执行的命令 由外壳执行。 descriptorspec 是一个索引数组,其中 key 表示描述符编号,value 表示 PHP 如何 将该描述符传递给子进程。管道将设置为 文件指针的索引数组,对应于 PHP 的任何结尾 创建的管道。返回值是一个资源代表 过程;你应该使用 proc_close() 释放它 看完了。

【讨论】:

【解决方案3】:

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

+----------------+-----------------+----------------+----------------+
|    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             |
+----------------+-----------------+----------------+----------------+
  • “显示输出”意味着它将输出流式传输到浏览器(或命令行输出,如果从命令行运行)。
  • “Can Get Output”表示您可以获取命令的输出并将其分配给 PHP 变量。
  • “退出代码”是命令返回的特殊值(也称为“返回状态”)。零通常表示成功,其他值通常是错误代码。

其他需要注意的事项:

  • shell_exec() 和反引号操作符做同样的事情。
  • 还有 proc_open() 和 popen() 允许您通过执行命令以交互方式读取/写入流。
  • 如果您还想捕获/显示错误消息,请将“2>&1”添加到命令字符串中。
  • 使用 escapeshellcmd() 转义可能包含问题字符的命令参数。
  • 如果将 $output 变量传递给 exec() 以存储输出,如果 $output 不为空,它会将新输出附加到它。所以你可能需要先 unset($output)。

【讨论】:

  • 哪些可以执行php文件?
  • @johnywhy none per se - 除非您明确调用 php cli 等。我想你想要include 和朋友
  • 此表是这些命令的最佳总结。
【解决方案4】:

这实际上都取决于您希望如何处理命令可能返回的输出,以及您是否希望您的 PHP 脚本等待被调用程序完成。

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

  • passthru 类似于exec() 函数,因为它执行一个命令。当 Unix 命令的输出是需要直接传回浏览器的二进制数据时,应使用此函数代替 exec()system()

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

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

【讨论】:

【解决方案5】:

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

如果您使用system()exec() 来执行这些脚本/程序,它根本不起作用。

问题:由于某种原因,您无法在 PHP 中使用 passthru() 执行 less

【讨论】:

  • 我不明白你在说什么。您可以从 CLI 和 (F)CGI(以及 mod_php)执行程序。可能存在系统强加的限制,例如 selinux。但是一个设置良好的系统会选择性地关闭这些。当然,共享​​>主机是另一回事,但您也不会为尊贵的客户提供共享​​>环境,不是吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-27
  • 2019-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-13
相关资源
最近更新 更多