'PHP script detect that it is an include

I have a PHP class file that is used as an include both through a web server and by a cron process. I am looking for a way to add some code to the head of the script so that I can detect if the script is being launched directly from the command line instead of being included in another script. This way I can make testing a bit easier by calling the script directly and having a function instantiate the object and execute some code on it without needing to create a wrapper script for it.

I tried using if (php_sapi_name() == 'cli') { but that tests true even if the script is being included in another script that was called from the command line.



Solution 1:[1]

You can check for the presence of $argv. If $argv[0] is set (the script name), your script is run from the command line.

Solution 2:[2]

Checking that $argv[0] is set lets you know if things were invoked from the command line; it does not tell you if the file was invoked directly or if it was included from another file. To determine that, test if realpath($argv[0]) == realpath(__FILE__).

Putting it all together:

if (isset($argv[0]) && realpath($argv[0]) == realpath(__FILE__))
    // This file was called directly from command line

Solution 3:[3]

You could test if $_SERVER['DOCUMENT_ROOT'] is empty. It will be empty in the command line execution since it's a variable predefined by apache.

What's interesting is $_SERVER['DOCUMENT_ROOT'] is defined but empty. I would have guessed it wouldn't be defined at all when using the cli.

You could also test if $argv is defined or its size (at least 1 when using CLI). I didn't test when including the file but if defined, sizeof($argv)would definitely be 0.

Other possible tests are $_SERVER['argc'] (0 when executed by a server, 1 when executed from CLI) and a strange $_SERVER['_'] defined to the path to the PHP binary, which is not defined at all when served.

To conclude, I would rely on $_SERVER['argc'] (or $argc) which is a direct count of the number of arguments passed to the command line: will always be 0 when the script is served. Relying on $argv is more complicated: you have to test if $argv[0] is set or if sizeof($argv) is > 0.

Solution 4:[4]

I have successfully used if (defined('STDIN')) as such a check. STDIN will be defined if the script is run from a shell, but not if it's in a server environment.

As you can see here and at the link Ryan provided in his comment, there are lots of possibilities.

Solution 5:[5]

if($_SERVER['SCRIPT_FILENAME']==__FILE__){
   // Directly
}else{
   // Included
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jeroen
Solution 2
Solution 3
Solution 4 eaj
Solution 5 Alvy