如何避免在PHP上显示“#!/ usr / bin / php”?

时间:2010-11-05 11:03:36

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

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

6 个答案:

答案 0 :(得分:19)

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

#!/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从命令行运行时,似乎会自动完成。

答案 1 :(得分:3)

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

答案 2 :(得分:2)

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

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

答案 3 :(得分: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(); }
...

(另外,请参见下面的“ UPDATE”部分,以获取我们可以为此做的最大工作...)

说明:

@Floris在这里的评论非常有意思:

  

是否需要一个ob_start();也一样也许值得一提。

您确定。但是哪里?什么时候?

需要考虑的情况:

  1. 正如Viliam所说的(并在PHP 7.2中得到了确认),幸运的是,当您使用php运行脚本时,php yourscript.php命令本身就把shebang吞噬了,所以整个技巧是多余的。

  2. 在Web模式下,它实际上是与配置有关的:如果output_buffering在配置中处于打开状态(当然,它通常处于打开状态,但not even the default),则{{1} }已经在脚本开始时隐式完成了(您可以使用ob_start进行检查)。因此,我们不能只是用ob_get_level()突然取消它并称其为一天:我们需要启动另一个,以保持水平平衡!

  3. 如果ob_end_clean在配置中处于关闭状态,那么,可悲的是,我们很不走运:output_buffering什么也不做,shebang将最终显示在页面顶部。

    注意:除了打开它以外,没有 修复程序。

  4. 在命令行模式下,约ob_get_clean()的{​​{3}}:

      

    此指令在PHP-CLI中始终处于关闭状态。

    但是,隐式shebang清理(请参见1.)并没有像3中那样失败,而是节省了一天。


*“修复”,意味着这种大胆的破解将在更多情况下起作用。如果您完全控制您的PHP环境,就可以了(就我而言)。否则,它仍然可能会意外地以许多微妙的方式破坏(考虑自动准备的代码,自定义扩展或控制输出缓冲的其他可能方式等)。另外,例如,当output_buffering在CLI模式下(没有缓冲)从其他脚本中删除时,the manual says:无论如何(无论是否经过过滤),shebang都会显示在输出中由呼叫者手动退出)。不仅如此,如果您碰巧有缓冲的话,它还会破坏自己的缓冲,同时还包含这样的脚本。


更新:只是为了好玩,这里有一个“几乎正确”的版本,可以与正在进行的缓冲(无论是隐式还是用户级)配合使用:

include

仅“几乎”正确,因为在Web模式下没有任何东西可以解决#!/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... } ,并且只有在调用脚本添加了显式output_buffering = 0时才能解决“不包含缓冲”的情况- ob_start包装。而且,上面的大多数警告仍然适用:各种细微差别仍然可以打破它(例如,当前输出缓冲区必须具有((默认是)ob_end_...)标记等)。

答案 4 :(得分:0)

使用php命令

调用脚本

答案 5 :(得分:-1)

上面的输出缓冲解决方案是一个黑客攻击。别这么做。

首先,您实际上更好地使用env命令来确定正在使用哪个php:

#!/usr/bin/env php

然后允许自己执行:

chmod +x myfile

因此,您现在只需运行:

,而不是调用&#39; php myfile&#39;
./myfile

从该文件夹中。希望这有帮助!