【发布时间】:2023-03-28 20:51:02
【问题描述】:
我希望 PHP 脚本同时在命令行和网站上运行(我使用 Apache 和 Nginx)所以我把 #!/usr/bin/php 放在我的脚本的第一行,但它出现在网站上...
【问题讨论】:
-
如果你已经使用 apache 来服务 PHP,只需将 nginx 配置为 apache 的反向代理。
标签: php apache shell nginx command-line-interface
我希望 PHP 脚本同时在命令行和网站上运行(我使用 Apache 和 Nginx)所以我把 #!/usr/bin/php 放在我的脚本的第一行,但它出现在网站上...
【问题讨论】:
标签: php apache shell nginx command-line-interface
@ViliamSimko 的wicked trick 几乎就在那里,但不幸的是,有缺陷。 (例如,它确实破坏了我的标头发送序列,尽管没有用 shebang 污染输出。)
TL;DR,这是修复*:
#!/usr/bin/php
<?php @ob_end_clean(); if(ini_get('output_buffering')) ob_start();
...
或者,看起来不那么淫秽,但仍然只是对同一罪行的委婉说法;):
#!/usr/bin/php
<?php if (ob_get_level()) { ob_end_clean(); ob_start(); }
...
(另请参阅下面的“更新”部分,也许我们可以对此做的最大努力......)
说明:
@Floris 在那里的 cmets 中有一个很好的观点:
你需要一个 ob_start();也?可能值得一提。
你肯定会的。但是哪里?什么时候?
需要考虑的案例:
ob_get_level()检查它)。所以,我们不能用ob_end_clean 突然取消它并收工:我们需要开始另一个,以保持水平平衡!
如果output_buffering 在配置中关闭,那么,可悲的是,我们运气不好:ob_get_clean() 什么都不做,shebang 最终会出现在页面顶部。
注意:除了打开它之外,没有解决这个问题。
在命令行模式下,the manual says 关于output_buffering:
此指令在 PHP-CLI 中总是关闭。
但是,隐式的 shebang 清理(参见 1.)并没有像 3. 那样以同样绝望的方式失败。
* “修复”这个大胆的破解将在更多情况下起作用。如果你完全控制了你的 PHP 环境,那会很好(就像我的情况一样)。否则,它仍然会以许多微妙的方式意外中断(考虑自动前置代码、自定义扩展或其他可能的方式来控制输出缓冲等)。此外,例如,当 included 在 CLI 模式下(没有缓冲)来自其他脚本时,you are still out of luck: shebang 无论如何都会出现在输出中(当然,除非由呼叫者)。不仅如此,它还会破坏你自己的缓冲,如果你碰巧有的话,同时包含这样一个淘气的脚本。
更新:只是为了好玩,这里有一个“几乎正确”的版本,它与正在进行的缓冲很好地配合,无论是隐式的还是用户级的:
#!/usr/bin/php
<?php
if (ob_get_level()) {
$buf = ob_get_clean();
ob_start();
// Refill the buffer, but without the shebang line:
echo substr($buf, 0, strpos($buf, file(__FILE__)[0]));
} // else { out of luck... }
仍然只是“几乎”正确,因为在 web 模式下没有任何东西可以修复 output_buffering = 0,并且只有调用脚本添加显式 ob_start - ob_end_... 包装才能解决“被包含而没有缓冲”的情况.此外,上面的大多数警告仍然适用:各种微妙之处仍然可以破坏它(例如,当前输出缓冲区必须具有(幸运的是默认)PHP_OUTPUT_HANDLER_CLEANABLE 标志等。)
【讨论】:
上面的输出缓冲解决方案是一个 hack。不要那样做。
首先,您实际上最好使用 env 命令来确定正在使用的 php:
#!/usr/bin/env php
然后给它自己执行的权限:
chmod +x myfile
因此,您现在只需运行,而不是调用“php myfile”:
./myfile
从那个文件夹。希望这会有所帮助!
【讨论】:
我使用输出缓冲解决了这个问题。 我的脚本现在看起来像这样:
#!/usr/bin/php
<?php
@ob_end_clean();
...
注意:文件末尾没有?>。这实际上是编写 PHP 脚本时的一个好习惯。这可以防止任何垃圾文本被意外打印。
注意:ob_end_clean() 的 PHP 文档说:
输出缓冲区必须由 ob_start() 启动 PHP_OUTPUT_HANDLER_CLEANABLE 和 PHP_OUTPUT_HANDLER_REMOVABLE 标志。 否则 ob_end_clean() 将不起作用。
这似乎是 PHP 从命令行运行时自动完成的。
【讨论】:
ob_start(); 吗?可能值得一提。
我通常认为将逻辑与表示分开是个好主意。当我做这样的事情时,我会尽可能多地放在一个库中,然后为它编写单独的 cli 和 web 界面。
也就是说,使用 php 命令调用它可能更容易解决。
【讨论】:
$argv 而不是 $_GET 交互)。所以没有真正需要从两者调用相同的 file。
您的代码中不需要#!/usr/bin/php,只需使用php 运行CLI 脚本,例如php /path/to/file.php 或/usr/bin/php /path/to/file.php。
【讨论】:
使用php 命令调用脚本
【讨论】:
php 命令运行脚本。但是,如果您想创建一个可执行脚本 (chmod +x yourscript.php),您需要将井号 (#!) 添加到脚本的第一行。