44

As per the title, is there PHP equivalent of __name__ == "__main__"?

Is there something that would work for both scripts executed through the command line and through a web request, or would a custom function be needed?

For those unfamiliar with Python, __name__ == "__main__" allows you to define a module file, and also have some things that allow you to run it if it is the entry point. The equivalent structure in PHP would resemble this:

// SomeClass.php
<?php
class SomeClass
{
    function doStuff() {
        echo "wahey!\n";
    }
}

// python, I know.
if (__name__ == "__main__") {
    $sc = new SomeClass;
    $sc->doStuff();
}
?>

// OtherClass.php
<?php
require_once("SomeClass.php");
class OtherClass
{
    public $yep;
}
?>

// command line:
php SomeClass.php     // outputs "wahey!"
php OtherClass.php    // outputs nothing

Note: zerkms' answer is the best, but is not quite right - it should read:

if (!debug_backtrace()) {
    // do useful stuff
}

This is significantly faster than !count(debug_backtrace()), which itself is about twice as fast as my solution involving realpath().

dreftymac
  • 31,404
  • 26
  • 119
  • 182
Shabbyrobe
  • 12,298
  • 15
  • 60
  • 87

4 Answers4

34
if (!count(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)))
{
    // some usefull stuff
}

look at https://www.php.net/manual/en/function.debug-backtrace.php for more details on debug_backtrace function

Community
  • 1
  • 1
zerkms
  • 249,484
  • 69
  • 436
  • 539
  • php_sapi_name() just tells me what the code is being executed in, which may provide a small part of the puzzle but doesn't solve the problem. I added some further information to the question to explain what I'm getting at. – Shabbyrobe Mar 10 '10 at 02:12
  • ... or debug_backtrace() ;-) look at the comment to the question – zerkms Mar 10 '10 at 02:13
  • Ahh, finally, I understand. debug_backtrace() works, and is thousands of times faster than the realpath. Update your answer to remove the reference to php_sapi_name() and update your example to read if (!debug_backtrace()) { /* do stuff */ } (or better) so I can accept. – Shabbyrobe Mar 10 '10 at 02:37
  • There's no need to do the count - it's actually only twice as fast as the realpath() call if you do the count around it, as opposed to thousands of times faster if you do the simple truth test. – Shabbyrobe Mar 10 '10 at 02:40
  • This is not the place to do optimizations. Your algorithms will work >10x times slower than this count(), but with count code become more obvious. – zerkms Mar 10 '10 at 02:50
  • 1
    how does it become more obivous? "if (!debug_backtrace())" *clearly* says in code "if there is no backtrace then ...". so, micro-optimisation it may be, but why code something that's arguably no clearer and is slower? – Shabbyrobe Mar 10 '10 at 04:08
  • 1
    because it become depending on implicit php casting array() -> false. i think that explicit "if count of elements is 0" is more cleaner. so i think the reason of using your case is only "readable from your point of view" but not "optimization issues" – zerkms Mar 10 '10 at 05:22
  • I think we'll have to agree to disagree on this. – Shabbyrobe Mar 10 '10 at 06:13
  • I'm with zerkms: The truth-tables for implicitly-converted PHP values are sufficiently large and full of edge-cases that it isn't very nice to whomever has to read your code later. – Darien Apr 25 '12 at 19:22
  • @Darien: with arrays->booleans it's pretty straightforward. `if (array)` is not tricky at all – zerkms May 01 '12 at 20:34
  • No, it still unreliable because you can't always know (without more checks) whether you have a "real" array, or an object which implements array-access methods. I consider using `if($possibleArray)` a bit like using `==` for object comparison in Java: Can work, but not quite as you want. – Darien May 22 '12 at 18:02
  • 2
    Just FYI, there's an error in the code snippet, it needs an extra closing bracket at the end of the if condition. Won't let me edit it because edits need to be 6 characters or more. – Craig Sefton Oct 27 '13 at 14:20
  • 2
    Very very very bad answer... **NO** explanation at all. You see, programmers should never use code because it works, that's the wrose bad practice of all. – Iharob Al Asimi Sep 10 '15 at 16:07
  • @iharob programmers have documentation in case if they don't know what a particular function does. Stackoverflow is not your personal tutor. – zerkms Sep 10 '15 at 22:12
  • 1
    Yes but it's a Q/A site. At least some explanation would be nice. Posting just code is bad. Especially given the fact that PHP doesn't have the best documentation. – Iharob Al Asimi Sep 10 '15 at 23:43
  • 1
    To optimize this a little, you can use `DEBUG_BACKTRACE_IGNORE_ARGS` flag to reduce memory usage – alexandre-rousseau Feb 26 '19 at 14:30
14
if ($argv && $argv[0] && realpath($argv[0]) === __FILE__) {
    // ...
}

works like a charm.

when you run php in command line, the name of php file will pass to program as $argv[0] and __FILE__ magic variable mean current file. So we check the running program is current file logically equals Python's __name__ == "__main__".

vr3C
  • 1,734
  • 19
  • 16
2
if(get_included_files()[0] == __FILE__) doStuff();
A Marchand
  • 21
  • 3
1

You probably want one of the "Magic Constants". Depending on what you are trying to do, __FILE__, __FUNCTION__ or __CLASS__ may give you the information you are after.

They are pretty self explanatory:

  • __FILE__gives you the current file name
  • __FUNCTION__ gives you the name of the current function
  • __CLASS__ gives you the name of the current class.

Check the manual for more details

Brenton Alker
  • 8,947
  • 3
  • 36
  • 37