3

Consider this:

#!/usr/bin/php
<?php
class Foo {
        static function bar () {
                echo "Foo->bar\n";
        }
}
if (PHP_SAPI === 'cli') {
        Foo::bar();
}
?>

I can execute this from CLI, but when I include it in, say, a CGI-run PHP script, the shebang ends up in the output.

I like simple scripts compact: I guess I could put the class part in a separate "lib"-file and have a simple wrapper for CLI use. BUT I'd like to keep it all in one place without having to worry about include paths etc.

Is this possible without ob_*-wrapping the include to capture the shebang (if this is even possible), or is it dumb to cram all of this into one file anyway? Alternatives/Thoughts/Best Practices welcome!

Edit: I'd like to put the script in my PATH, so calling I'd rather not call it by php file.php. See my comment to @misplacedme's answer

4
  • You can get away without needing the shebang just make sure your call full paths to your php binary and it'll be fine Commented Jul 25, 2013 at 14:05
  • @Dave - isn't this what misplacedme answered? Sorry if I'm wrong, I don't really understand "your call full paths to"... Commented Jul 25, 2013 at 14:13
  • I know this is old, and @kubi, you don't seem to be hanging around here much, but if you still see this, just wondering: what have you ended up with? AFAIK it's not possible to solve this problem even today (PHP 7.2). It would need at least a new command-line option (and/or ini setting) to tell PHP not to output the shebang, if it exists. Commented Nov 12, 2018 at 22:17
  • Since this was more about convenience&curiosity than necessity I abandoned the issue, @Sz. And I do lurk here quite a lot. Commented Nov 18, 2018 at 11:27

2 Answers 2

2

I'm rather late to this one, but if anyone still cares, you can solve this on Linux by registering a binfmt handler. As a one-off (resets after reboot):

echo ":PHP:M::<?php::/usr/bin/php:" > /proc/sys/fs/binfmt_misc/register

With this in place, any file that starts with the "magic" string "<?php" will be executed by running it with /usr/bin/php.

You can make this registration permanent by saving the line a file in /etc/binfmt.d

You can remove the registration with:

echo -1 > /proc/sys/fs/binfmt_misc/PHP
Sign up to request clarification or add additional context in comments.

1 Comment

this feels... cursed :)
1

It's actually easy.
Remove the shebang and when you run the script, run it as
php scriptname.php OR /path/to/php scriptname.php
instead of
./scriptname.php

Running php script.php will look in only the current directory, or any directory within PATH. If you absolutely have to run it that way, add it. export PATH=$PATH:/path/to/php/script/folder(in bash)
That will mess up includes unless you're using full paths within the script.
No matter what you do, you'll have to use full paths somewhere.

5 Comments

Ah, I didn't mention that I want to have the script in my PATH. Something like cat somefile | php /usr/local/share/foo.bar.php | sed … is no fun.
Normally php is included in your path, or you can add it. Is neither option available to you?
php sure is, but my script isn't. Doesn't php file look for file only in working directory?
I added a little extra to my post. The paths problem is a separate issue really.
yeah, this sort of works... I'll investigate how this affects a real-world case. Real-world weird edge case. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.