如何避免在 PHP 上显示“#!/usr/bin/php”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4105278/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I avoid showing "#!/usr/bin/php" on PHP?
提问by brainsqueezer
I want PHP scripts to run both on command line and website (I use Apache and Nginx) so I put #!/usr/bin/php in the first line of my scripts but that appears on the website...
我希望 PHP 脚本同时在命令行和网站上运行(我使用 Apache 和 Nginx),所以我将 #!/usr/bin/php 放在脚本的第一行,但它出现在网站上...
回答by Viliam Simko
I solved the problem using output buffering. My script now looks like this:
我使用输出缓冲解决了这个问题。我的脚本现在看起来像这样:
#!/usr/bin/php
<?php
@ob_end_clean();
...
Note:There is no ?>
at the end of the file. This is actually a good practice when writing PHP scripts. This prevents any garbage text to be accidentally printed.
注意:?>
文件末尾没有。这实际上是编写 PHP 脚本时的一个好习惯。这可以防止意外打印任何垃圾文本。
Note:The PHP documentation for ob_end_clean()
says that:
注意:PHP 文档ob_end_clean()
说:
The output buffer must be started by ob_start() with PHP_OUTPUT_HANDLER_CLEANABLE and PHP_OUTPUT_HANDLER_REMOVABLE flags. Otherwise ob_end_clean() will not work.
输出缓冲区必须由带有 PHP_OUTPUT_HANDLER_CLEANABLE 和 PHP_OUTPUT_HANDLER_REMOVABLE 标志的 ob_start() 启动。否则 ob_end_clean() 将不起作用。
It seems that this is done automatically when PHP runs from command line.
当 PHP 从命令行运行时,这似乎是自动完成的。
回答by David Kurid?a
There is no need to have #!/usr/bin/php
in your code, just run CLI script using php
, for example php /path/to/file.php
or /usr/bin/php /path/to/file.php
.
有没有需要有#!/usr/bin/php
你的代码,只需使用运行CLI脚本php
,例如php /path/to/file.php
或/usr/bin/php /path/to/file.php
。
回答by Sz.
@ViliamSimko's wicked trickis almost there, but, unfortunately, flawed. (It did actually break my header-sending sequence, for instance, despite not polluting the output with the shebang.)
@ViliamSimko 的恶作剧几乎就在那里,但不幸的是,有缺陷。(例如,尽管没有用 shebang 污染输出,但它确实打破了我的标头发送序列。)
TL;DR, here's the fix*:
TL; DR,这是修复*:
#!/usr/bin/php
<?php @ob_end_clean(); if(ini_get('output_buffering')) ob_start();
...
or, less obscene-looking, but still just an euphemism for the same offense ;) :
或者,看起来不那么淫秽,但仍然只是同一罪行的委婉说法;):
#!/usr/bin/php
<?php if (ob_get_level()) { ob_end_clean(); ob_start(); }
...
(And see also the "UPDATE" part below for perhaps the maximum we can do about this...)
(另请参阅下面的“更新”部分,了解我们对此所能做的最大的事情......)
Explanation:
解释:
@Floris had a very good point in the comments there:
@Floris 在评论中有一个很好的观点:
Do you need an ob_start(); as well? Probably worth mentioning.
你需要一个 ob_start(); 还有?大概值得一提。
You sure do. But where? And when?
你肯定会。但是哪里?什么时候?
Cases to consider:
需要考虑的情况:
As Viliam said (and just confirmed it with PHP 7.2), the shebang is fortunately eaten by the
php
command itself, when you run your script withphp yourscript.php
, so the entire trick is redundant.In web mode, it's actually config-dependent: if
output_buffering
is on in the config (and sure enough, it's usually on, but it's not even the default), anob_start
has already been done implicitlyat the start of the script (you can check it withob_get_level()
). So, we can't just abruptly cancel it with anob_end_clean
and call it a day: we need to start another one, to keep the levels balanced!If
output_buffering
is off in the config, then, sad face, we are out of luck:ob_get_clean()
does nothing, and the shebang will end up in the top of the page.Note: there is nofix for this one, other than turning it on.
In command-line mode, the manual saysabout
output_buffering
:This directive is always Off in PHP-CLI.
But, instead of failing the same hopeless way as in 3., the implicit shebang cleanup (see 1.) saves the day.
正如 Viliam 所说(并且刚刚用 PHP 7.2 确认),幸运的是
php
,当您使用 运行脚本时,shebang 被命令本身吃掉了php yourscript.php
,所以整个技巧都是多余的。在 web 模式下,它实际上是依赖
output_buffering
于配置的:如果在配置中打开(当然,它通常是打开的,但它甚至不是默认的),一个ob_start
已经在脚本开始时隐式完成(你可以检查它与ob_get_level()
)。所以,我们不能突然用一个取消它ob_end_clean
并结束它:我们需要开始另一个,以保持水平平衡!如果
output_buffering
在配置中关闭,那么,悲伤的脸,我们不走运:ob_get_clean()
什么都不做,shebang 将最终出现在页面顶部。注意:除了打开它之外,没有其他修复方法。
在命令行模式,手动说大约
output_buffering
:该指令在 PHP-CLI 中始终处于关闭状态。
但是,不是像 3. 那样以同样绝望的方式失败,而是隐式 shebang 清理(参见 1.)挽救了这一天。
* "Fix" in the sense that this audacious hack will work in a lot more cases. If you are in full control of your PHP env., it can be just fine (as is in my case). Otherwise, it can still break in lots of subtle ways unexpectedly (consider auto-prepended code, custom extensions, or other possible ways to control output buffering etc.). Also, for example, when include
d from other scripts in CLI mode (where there's no buffering), you are still out of luck: the shebang will show up in the output, no matter what (unless, of course, filtered out manually by the caller). Not only that, but it would also break up your own buffering, if you happened to have any, while including such a naughtified script.
*“修复”,因为这个大胆的黑客将在更多情况下起作用。如果你完全控制你的 PHP 环境,它可以很好(就像我的情况一样)。否则,它仍然可能以许多微妙的方式意外中断(考虑自动预置代码、自定义扩展或其他可能的控制输出缓冲的方法等)。此外,例如,当include
d 从处于 CLI 模式(没有缓冲)的其他脚本中时,您仍然不走运:无论如何,shebang 都会显示在输出中(当然,除非由呼叫者)。不仅如此,它还会破坏您自己的缓冲(如果您碰巧有任何缓冲),同时包含这样一个淘气的脚本。
UPDATE:Just for the fun of it, here's an "almost correct" version, which plays along nicely with an ongoing buffering, be it implicit or user-level:
更新:只是为了好玩,这里有一个“几乎正确”的版本,它与正在进行的缓冲很好地配合,无论是隐式还是用户级:
#!/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... }
Still only "almost" correct, as nothing can fix output_buffering = 0
in web mode, and the "being included with no buffering" case can only be solved if the calling script adds an explicit ob_start
- ob_end_...
wrapping. Also, most of the caveats above still apply: various subtleties can still break it (e.g. the current output buffer must have the (fortunately default) PHP_OUTPUT_HANDLER_CLEANABLE
flag etc.).)
仍然只是“几乎”是正确的,因为没有什么可以固定output_buffering = 0
在网页模式下,如果调用脚本添加一个明确的“被列入无缓冲”的情况下,只能解决ob_start
-ob_end_...
包装。此外,上面的大多数警告仍然适用:各种微妙之处仍然可以打破它(例如,当前输出缓冲区必须具有(幸运的是默认)PHP_OUTPUT_HANDLER_CLEANABLE
标志等)。)
回答by Chris
I generally find it a good idea to separate logic from presentation. When I do something like this, I put as much as possible in a library, and then write separate cli and web interfaces for it.
我通常认为将逻辑与表示分开是个好主意。当我做这样的事情时,我将尽可能多的放在一个库中,然后为它编写单独的 cli 和 web 界面。
That said, calling it with the php command is probably an easier fix.
也就是说,使用 php 命令调用它可能更容易解决。
回答by Petah
Call the script using the php
command
使用php
命令调用脚本
回答by delboy1978uk
The output buffering solution above is a hack. Don't do that.
上面的输出缓冲解决方案是一个黑客。不要那样做。
First thing, you are actually better using the env command to determine which php is being used:
首先,您实际上最好使用 env 命令来确定正在使用哪个 php:
#!/usr/bin/env php
Then give it permission to be executed by itself:
然后给它自己执行的权限:
chmod +x myfile
So instead of calling 'php myfile', you now just run:
因此,您现在只需运行:
./myfile
From that folder. Hope this helps!
从那个文件夹。希望这可以帮助!