【问题标题】:Identify development vs. production server in PHP在 PHP 中识别开发服务器与生产服务器
【发布时间】:2009-09-11 18:27:53
【问题描述】:

我每天使用两台应用服务器:一台开发,一台生产。来自不同开发人员的各种应用程序都存在于这些盒子上,以及一些通过 cron 运行的脚本。目前,我正在使用-D flag 到httpd,以便我可以在代码中识别我的生产服务器,即。 isset($_SERVER['DEV'])。不幸的是,这不适用于从命令行运行的脚本,因为它们不在 Apache 保护伞下。

基本上,我想要一种清晰、简单的方法来识别每行代码都可以使用的开发与生产

我排除的:

  • auto_prepend_file -- 我们已经在一些应用程序中使用了这个指令,你不能有多个自动前置。

我目前正在探索的内容:

  • 自定义扩展——我确信创建一个只定义一个新常量(可能受 ini 设置影响)的新扩展不会是世界上最难的事情,但我在这方面没有经验。

那么,有什么技巧可以识别不涉及将代码注入每个脚本或应用程序的开发/产品?

【问题讨论】:

    标签: php


    【解决方案1】:

    我之前工作的一家公司使用以下后缀服务器的约定:

    • L = 直播
    • D = 开发
    • T = 测试
    • U = UAT

    这使得确定您在 Apache 内部和外部工作的环境变得相当简单。

    【讨论】:

    • 好东西。 UAT = 用户验收测试?
    • 这种方法的一个主要警告是,这意味着公司拥有即控制所有服务器。例如,如果您使用第 3 方进行生产,我怀疑他们是否允许您指定自己的主机名
    【解决方案2】:

    我最终使用了$_ENV['HOSTNAME'],并以php_uname("n") 作为备份:

    /**  
     * Returns true if we are working on a development server, determined by server's
     * hostname. Will generate an error if run on an unknown host.
     */
    public static function isdev()
    {
      static $isdev = null;
    
      // don't run function body more than once
      if( null !== $isdev ) {
        return $isdev;
      }    
    
      // prefer HOSTNAME in the environment, which will be set in Apache.
      // use `uname -n' as a backup.
      if( isset( $_ENV['HOSTNAME'] ) ) {
        $hostname = $_ENV['HOSTNAME'];
      } else {
        $hostname = php_uname("n");
      }    
    
      switch( $hostname ) {
        case 'production1.example.com':
        case 'production2.example.com':
        case 'production3.example.com': $isdev = false; break;
    
        case 'dev1.example.com':
        case 'dev2':
        case 'dev2.example.com': $isdev = true; break;
    
        default: trigger_error( 'HOSTNAME is set to an unknown value', E_USER_ERROR );
      }    
    
      return $isdev;
    }
    

    【讨论】:

      【解决方案3】:

      我想到了这个

      if(filter_var(ini_get('display_errors'), FILTER_VALIDATE_BOOLEAN))
      {
          // development
      } 
      else {
          // production
      }
      

      或者更好的方法

      define('IN_DEVELOPEMENT', filter_var(ini_get('display_errors'), FILTER_VALIDATE_BOOLEAN));
      

      【讨论】:

        【解决方案4】:

        使用环境变量

        只需设置一个环境变量。它适用于 Windows 和 linux,现在它们甚至被称为同一个东西。然后检查$_ENV["DEVVSPROD"]

        【讨论】:

        • 不错。我必须让我们的系统管理员将export DEV=1 放到全局 bash/tsch rc 文件中,并且它有可能被env -i 破坏。我想知道 cron'd 脚本会得到什么样的环境。
        • 实际上,crontab 条目本身可以包含环境变量分配,另外,当 cron 启动 shell 运行进程时,将应用正常的 shell 规则。另见pam_env(8)。呵呵,相信grub(8)可以把环境变量传给内核。
        • 我喜欢它。向每个人的系统添加环境变量非常简单,用户不可能进行欺骗。这感觉像是我还没有找到的最安全可靠的答案——直到你在重新加载系统时忘记设置变量,哈哈。如果您正在使用命令行,请确保使用getenv(),因为超全局变量通常不可用。 define('DEV', getenv('DEV')); 运行良好 - 如果变量不存在,该函数返回 false
        • 意识到如果您(或新团队成员)忘记设置变量或由于启动脚本失败而丢失变量,您的应用现在正在使用实时数据。那可能不是你想要的。
        【解决方案5】:

        我通常只是这样做:

        if ($_SERVER['HTTP_HOST'] == 'localhost') // or any other host
        {
             // development
        }
        
        else
        {
             // production
        }
        

        【讨论】:

        • define('IN_PRODUCTION', ($_SERVER['HTTP_HOST'] === 'localhost'));
        • 我知道这是旧的,但我想指出这不是 100% 准确的。如果您将生产服务器设置为捕获所有主机名(这通常很常见),则有人可以将 HTTP Host 标头制作为 localhost,并可能获得他们不应该看到的调试信息。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-11
        • 1970-01-01
        相关资源
        最近更新 更多