1

看起来有两种典型的方法可以确定脚本是否通过命令行运行。

  1. if ( defined('STDIN') ) # Running via CLI
  2. if (PHP_SAPI === 'cli') # Running via CLI

由于它们都被使用和推荐,我认为它们都运行良好。我的问题是:是否有任何边缘情况会失败?哪个是首选,为什么?

4

1 回答 1

1

我永远不会依赖if (defined('STDIN'))。仅仅是因为,如果未定义STDIN常量,我可以自己定义它:

defined('STDIN') || define('STDIN', 'random value');

这将具有以下任何代码,使用if (defined('STDIN'))相信它在命令行上运行,而PHP_SAPI始终被定义。
您必须考虑的另一件事是名称空间。当然,这会影响这两项检查,但您也可以使用php_sapi_name功能来确定,或者简单地:

if (\PHP_SAPI === 'cli')

在我看来,这比以下更具可读性:

if (defined('\\STDIN'))

所以基本上,使用这三个选项中的任何一个,但请注意,它STDIN也可以是用户定义的常量。PHP_SAPI或者返回值php_sapi_name总是字符串(AFAIK),并且您知道在运行 CLI 脚本时期望什么值:'cli'. 但是,如果由于某种原因您不相信这一点,我看到人们这样做:

if (stristr(PHP_SAPI, 'cli') && strpos(PHP_SAPI, 'cli') === 0)

但这只是偏执狂,恕我直言。
有些人只是检查$argv,但这意味着该register_argc_argv设置已启用,默认情况下是启用的,但可以禁用,您可以反过来使用以下内容进行反击:

#!/var/bin/php -n
<?php
    if (!is_array($argv))
    {
        exit();
    }

通过 using /path/to/php -n,您没有使用任何 ini 文件,因此将使用默认设置,并且由于默认设置为register_argc_argv1,$argv因此将可用。

于 2013-08-09T14:00:39.447 回答