我希望PHP脚本在命令行和网站上运行(我使用Apache和Nginx)所以我把#!/ usr / bin / php放在我的脚本的第一行但是出现在网站上...... < / p>
答案 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();也一样也许值得一提。
您确定。但是哪里?什么时候?
需要考虑的情况:
正如Viliam所说的(并在PHP 7.2中得到了确认),幸运的是,当您使用php
运行脚本时,php yourscript.php
命令本身就把shebang吞噬了,所以整个技巧是多余的。
在Web模式下,它实际上是与配置有关的:如果output_buffering
在配置中处于打开状态(当然,它通常处于打开状态,但not even the default),则{{1} }已经在脚本开始时隐式完成了(您可以使用ob_start
进行检查)。因此,我们不能只是用ob_get_level()
突然取消它并称其为一天:我们需要启动另一个,以保持水平平衡!
如果ob_end_clean
在配置中处于关闭状态,那么,可悲的是,我们很不走运:output_buffering
什么也不做,shebang将最终显示在页面顶部。
注意:除了打开它以外,没有 修复程序。
在命令行模式下,约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
从该文件夹中。希望这有帮助!