在PHP CLI脚本中检测环境


Detecting the environment in PHP CLI scripts

我在StackOverflow上看到了几个问题,这些问题涉及如何在通过Apache提供脚本时检测用户环境,以及如何建立这样一个完美工作的系统。该脚本依赖于Apache设置的Environment变量。

现在我正在创建几个需要在php-CLI模式下运行的工具,但我不知道如何在CLI模式下检测环境,因为那里不存在apacheenv-var。

我正在考虑用gethostname((读取服务器的主机名,但不知道这是否是最好的解决方案和可靠的解决方案。

使用PHP 在CLI模式下运行时,检测环境的最佳方法是什么

澄清:
我不是在寻找一种方法来检测我是否正在从CLI运行脚本,这个基础已经涵盖在内。我正在寻找一种方法,通过CLI来确定我的脚本在哪个服务器上运行(DEV、STAGING或PRODUCTION(,这样就不会读取在我的VHOST中设置的apache env变量,这些变量在通过浏览器运行同一脚本时存在。

您可以使用php_uname('n')获取当前机器的主机名。从那里开始,您的实现可以根据主机名、硬编码值或其他配置文件中的模式来确定它是生产、暂存还是开发。

我会在/etc/environment(或基于操作系统风格的等效变量(中设置变量,例如MYAPP_ENV=STAGING

这将自动神奇地被CLIphp运行时获取,并在$_SERVER全局变量中可用,如下所示:_$SERVER['MYAPP_ENV']

如果您希望无论脚本是从HTTPD还是CLI运行都能正常工作,那么您还需要在.htaccess或vhosts.conf apache文件中为您的应用程序设置此变量(假设为apache(,如下所示:SetEnv MYAPP_ENV STAGING

从应用程序代码中,您只需要引用_$SERVER即可访问此变量,无论调用是从CLI还是通过http。

你必须在你的机器上设置两次这个变量——一次用于Apache,一次用于CLI,这很糟糕,但至少从应用层来看,在读取环境变量时,你可以不知道执行运行时。

我认为你所说的环境是指操作系统,无论是否使用Apache,都有一种防傻的方法:常量PHP_OS和函数php_uname()

如果你的意思是"检测它是否是CLI",只需测试isset($GLOBALS['argv'])——它不会使用Web服务器设置,而是在它是CLI的情况下设置。或者你可以做(PHP_SAPI === 'cli')

我一直使用与服务器主机名匹配的命名:设想主机名如下:-server.production.product.com-server.development.project.com

您可以使用主机名称和一些bash(或php(魔术来确定主机:

$server_env = `hostname | cut -d '. -f 2`; # production or development
# pure php (5.3+) method:
$server_name = gethostname();
$server_name_arr = explode( '.', $server_name );
$server_env = $server_name_arr[1];

主机名当然应该不同;(干杯

您可能需要在系统范围内设置env,而不仅仅是从apache,然后apache脚本可以读取它,cli脚本可以从env读取它,您可以通过像这样的/etc/profile为交互式shell设置它们

APP_ENV="暂存">

导出APP_ENV

(您可以通过类似的2行来完成,这样脚本中的其他内容稍后也可以引用APP_ENV并获得相同的值,否则APP_ENV在重新运行之前对该shell无效(

然后只需从cli或apache上的程序中检查$_ENV,但apache可能需要重新启动,我已经实践了一段时间,但它也非常适合数据库连接的json编码设置,但这是另一篇文章的内容。

为了不定义两次环境变量,我(在Ubuntu中(做了以下操作。

例如,在/etc/profile.d/env.sh中定义变量export APPLICATION_ENV=生产

通过添加以下行将该文件包含在/etc/apache2/envvars中:./etc/profile.d/env.sh

重新启动apache2和shell以重新加载环境。

$cli = false;
if (isset($argc)) $cli = true;

请参阅:$argc

即使这是一个古老的线程,您也可以在php.ini中设置和检索变量,在php.ini可以在一个位置设置值,并通过服务器或cli:提供这些值

在php.ini中:

[PHP]
MY_ENVIRONMENT = development
;;;;;;;;;;;;;;;;;;;
; About php.ini   ;
;;;;;;;;;;;;;;;;;;;
; PHP's initialization file, generally called php.ini, is responsible for...

然后从cli:

php > echo get_cfg_var('MY_ENVIRONMENT');
development

和一个网页(注意:您必须重新启动apache才能使用此变量(:

<?php
echo "you are in: " . get_cfg_var('MY_ENVIRONMENT');
// you are in: development

我有很多依赖sh/Bash环境变量的cli脚本,通常不止一小部分。为了让我的生活更轻松,我把它们都加载进去。

输出是一个数组,其键等于shell环境变量名,值是变量设置的字符串。

例如$env_var['HOME']=>quot/家庭/用户";

要使用此代码,请确保运行的任何shell都支持printenv命令。

$sh_env_arr = explode(PHP_EOL, shell_exec('printenv'));
    foreach($sh_env_arr as $var_lines) {
        $vals = explode('=', $var_lines);
        /* Some shell vars can have multiple equals signs as part of the value.
        We need to make those into a single string */
        if (isset($vals[2])){
            foreach (range(2, count($vals)-1) as $i) {
                $vals[1] = $vals[1].'='.$vals[$i];
            }
        }
        if (!isset($vals[1])) {$vals[1] = "";}
        $env_var[$vals[0]] = $vals[1];
    }

我甚至用容器玩过这个游戏,因为你可以在环境变量启动时从主机传递它们。这有助于将敏感信息(数据库信誉等(获取到脚本中。

据我所知,在shell中运行时可以使用$_ENV和getenv((,就像在web服务器下运行时一样,尽管ENV中可用的实际值可能会有所不同。