【问题标题】:How can I avoid showing "#!/usr/bin/php" on PHP?如何避免在 PHP 上显示“#!/usr/bin/php”?
【发布时间】:2023-03-28 20:51:02
【问题描述】:

我希望 PHP 脚本同时在命令行和网站上运行(我使用 Apache 和 Nginx)所以我把 #!/usr/bin/php 放在我的脚本的第一行,但它出现在网站上...

【问题讨论】:

  • 如果你已经使用 apache 来服务 PHP,只需将 nginx 配置为 apache 的反向代理。

标签: php apache shell nginx command-line-interface


【解决方案1】:

@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();也?可能值得一提。

你肯定会的。但是哪里?什么时候?

需要考虑的案例:

    1234563 /p> 1234563 em>隐式在脚本的开头(你可以用ob_get_level()检查它)。所以,我们不能用ob_end_clean 突然取消它并收工:我们需要开始另一个,以保持水平平衡!
  1. 如果output_buffering 在配置中关闭,那么,可悲的是,我们运气不好:ob_get_clean() 什么都不做,shebang 最终会出现在页面顶部。

    注意:除了打开它之外,没有解决这个问题。

  2. 在命令行模式下,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 标志等。)

【讨论】:

    【解决方案2】:

    上面的输出缓冲解决方案是一个 hack。不要那样做。

    首先,您实际上最好使用 env 命令来确定正在使用的 php:

    #!/usr/bin/env php
    

    然后给它自己执行的权限:

    chmod +x myfile
    

    因此,您现在只需运行,而不是调用“php myfile”:

    ./myfile
    

    从那个文件夹。希望这会有所帮助!

    【讨论】:

    • 我认为不赞成票是因为您所描述的(使文件可执行,并使用 shebang 行)是提问者已经在做的事情。除了,他有时还通过网络服务器调用同一个文件。因此,在浏览器中,shebang 行会打印出来。他正在为此寻求解决方法。输出缓冲 hack 似乎是唯一的方法。
    • 是的,他不应该那样做。最好在另一个文件中包含具有实际逻辑的可执行 CLI 脚本,并让他的网页 PHP 执行相同操作,因此它们共享相同的代码并且 shebang 不会显示
    • 用该建议更新您的答案可能是解决否决票的一种方法(并不是说任何人似乎都检查过人们是否修复了他们已投票的答案...... sigh )
    【解决方案3】:

    我使用输出缓冲解决了这个问题。 我的脚本现在看起来像这样:

    #!/usr/bin/php
    <?php
    @ob_end_clean();
    ...
    

    注意:文件末尾没有?&gt;。这实际上是编写 PHP 脚本时的一个好习惯。这可以防止任何垃圾文本被意外打印。

    注意:ob_end_clean() 的 PHP 文档说:

    输出缓冲区必须由 ob_start() 启动 PHP_OUTPUT_HANDLER_CLEANABLE 和 PHP_OUTPUT_HANDLER_REMOVABLE 标志。 否则 ob_end_clean() 将不起作用。

    这似乎是 PHP 从命令行运行时自动完成的。

    【讨论】:

    • 您还需要ob_start(); 吗?可能值得一提。
    • 这很漂亮。
    • 好主意,但@Floris 在这里有一个关键点。请查看我的answer,我已在其中解决了该问题。
    【解决方案4】:

    我通常认为将逻辑与表示分开是个好主意。当我做这样的事情时,我会尽可能多地放在一个库中,然后为它编写单独的 cli 和 web 界面。

    也就是说,使用 php 命令调用它可能更容易解决。

    【讨论】:

    • +1 用于逻辑分离。通常 CLI 和 web 将需要单独的接口(例如与 $argv 而不是 $_GET 交互)。所以没有真正需要从两者调用相同的 file
    【解决方案5】:

    您的代码中不需要#!/usr/bin/php,只需使用php 运行CLI 脚本,例如php /path/to/file.php/usr/bin/php /path/to/file.php

    【讨论】:

    • 但是如果你想创建一个可以从shell运行的可执行脚本,你需要解决这个问题。
    【解决方案6】:

    使用php 命令调用脚本

    【讨论】:

    • 确实可以使用php 命令运行脚本。但是,如果您想创建一个可执行脚本 (chmod +x yourscript.php),您需要将井号 (#!) 添加到脚本的第一行。
    猜你喜欢
    • 1970-01-01
    • 2018-04-09
    • 2017-01-06
    • 2021-03-25
    • 2014-08-08
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    相关资源
    最近更新 更多