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 eas开发者_如何学运维ier 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.
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
You can check for the presence of $argv
. If $argv[0]
is set (the script name), your script is run from the command line.
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.
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.
if($_SERVER['SCRIPT_FILENAME']==__FILE__){
// Directly
}else{
// Included
}
精彩评论