328

有什么区别?

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

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

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

4

5 回答 5

209

它们的目的略有不同。

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

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

于 2009-04-09T04:50:58.110 回答
140

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

system( )函数

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

exec( )函数

system 函数非常有用且强大,但它最大的问题之一是程序生成的所有文本都直接进入输出流。在某些情况下,您可能希望格式化生成的文本并以某种不同的方式显示它,或者根本不显示它。

为此,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() 释放它。

于 2014-01-09T09:23:48.543 回答
129

以前的答案似乎都有点令人困惑或不完整,所以这里有一张差异表......

+----------------+-----------------+----------------+----------------+
|    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) 。
于 2016-09-24T21:58:45.490 回答
22

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

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

  • passthruexec()与执行命令的功能相似。当 Unix 命令的输出是需要直接传回浏览器的二进制数据时,exec()应使用此函数。system()

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

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

于 2009-04-09T04:51:57.873 回答
10

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

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

Gotcha:由于某种原因,您无法在 PHP 中执行lesswith 。passthru()

于 2009-04-09T17:13:17.737 回答