ChatGPT解决这个技术问题 Extra ChatGPT

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

有什么区别?

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

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

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

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

Z
ZioCain

它们的目的略有不同。

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/…
5
5 revs, 2 users 89%

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


shell_exec 的执行速度比其他的要快。
您应该提及您已直接从 ChipmunkNinja 复制您的答案。
@TachyonVortex 幸运的是,他确实逐字复制了答案,因为 ChipmunkNinja 不再存在。
那么 popen 和 proc_open 呢?
N
Norbert Wagner

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

+----------------+-----------------+----------------+----------------+
|    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 本身没有 - 除非您明确调用 php cli 等。我想你想要include和朋友
该表是这些命令的最佳总结。
k
kenorb

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

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

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

系统执行外部程序并显示输出,但仅显示最后一行。

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


还要注意 exec 可以在某些版本的 php 中执行循环。见stackoverflow.com/questions/3615713/…
t
the

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

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

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


我不明白你在说什么。您可以从 CLI 和 (F)CGI(以及 mod_php)执行程序。可能存在系统强加的限制,例如 selinux。但是一个设置良好的系统会选择性地关闭这些。当然,共享主机是另一回事,但您也不会为尊贵的客户提供共享环境,不是吗?