根据服务器环境参数来区分
【转】https://blog.youkuaiyun.com/default7/article/details/49329585
Apache
指令中加入
SetEnv RUN_ENV dev
Nginx 中
fastcgi_param RUN_ENV 'dev'
然后重启 Apache/Nginx,我们用 php
$_SERVER
来查看是否有 $_SERVER['RUN_ENV'];
在代码中可以这么使用
// 定义运行环境
define('RUN_ENV', isset($_SERVER['RUN_ENV']) ? $_SERVER['RUN_ENV'] : 'production');
require_once DIR_ROOT . '/system/config/' . RUN_ENV . '/config.php';
利用 php.ini 参数设置来区分
我们可以在 php.ini
中直接设置参数,比如我设置了一个参数名为 pro.env
的参数,值为 pro
[Environment]
pro.env=pro
代码中可以这么使用
// 用于cli模式下的判断
$env = ($tmpEnv = get_cfg_var('pro.env')) ? $tmpEnv : 'ceshi';
if (isset($env)) {
define('WEB_ENV', $env);
return require __DIR__ . DIRECTORY_SEPARATOR . 'Config' . DIRECTORY_SEPARATOR . WEB_ENV . '.env.php';
}
利用 php-fpm.conf 设置参数
env[RUNTIME_ENVIROMENT] = test
Caution 由于这些设定是以 FastCGI 标头传递给 php-fpm,php-fpm 不应绑定到外部网可以访问的地址上,否则任何人都能修改 PHP 的配置选项了。参见 listen.allowed_clients。
使用 http 或者 https 来区分
如果访问是通过 https 协议过来的请求,那 $_SERVER
中应该是有 $_SERVER['HTTPS']
,对于 HTTPS
的判断可以使用下面的方法。
function getIsSecureConnection ()
{
return ((isset($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'on') === 0) || (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 1)
|| (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') === 0));
}
那有的同学就会说了,我打印 $_SERVER
并没有看到有 HTTPS
这个参数啊,那没有的话你就需要去设置下你的 Apache
或者 Nginx
,这里我仅仅是测试了 Nginx
,可以这么设置。参数部分的解释并不那么准确仅做参考,具体可查看 Nginx
官方文档。
location / {
proxy_set_header X-Forwarded-Proto https; # 真实来源协议
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 真实来源IP地址
proxy_set_header Host $http_host; # 真实访问域名信息
proxy_redirect off; # 禁止重定向
proxy_pass http://www.baidu.com:80; # 代理转发
}
然后重启 Nginx
后, 查看$_SERVER['HTTPS']
是否存在了。
通过区分这个 http
和 https
我们可以在队列方面生产数据的时候加以区分,那消费者也可以通过这个 http
或者 https
来区分将数据消费到对应的哪个数据库,因为消费者并不知道要将数据消费到哪里,所以需要你指定。
因为这里我仅仅测试了用 http
和 https
这种方法来区分。那上面两种的效果类似,可自行测试。
假如我们要生产数据。我们把正式数据放到键为 https
的数组中,把 测试数据放到 http
的数组中。
// Publisher
$msgbody = [];
if (self::getIsSecureConnection()) {
$msgbody['https'] = $mqbody;
} else {
$msgbody['http'] = $mqbody;
}
$msgbody = json_encode($msgbody);
……
$psrContext->createMessage($msgbody);
// Consumer
while (true) {
if ($message = $consumer->receive()) {
if (self::getIsSecureData($message->getBody())) {
$https_data = self::formatIsSecureData($message->getBody());
} else {
$http_data = self::formatIsSecureData($message->getBody());
}
$consumer->acknowledge($message);
}
}
public static function getIsSecureData ($input = "") // json
{
// check is secure data is http or https
$input = json_decode($input, true);
if (isset($input['http']) && !empty($input['http'])) {
return false; // http
} else if (isset($input['https']) && !empty($input['https'])) {
return true; // https
}
}
public static function formatIsSecureData ($input = "") // json
{
// format is secure data to http or https
$input = json_decode($input, true);
if (isset($input['http']) && !empty($input['http'])) {
return $input['http']; // http
} else if (isset($input['https']) && !empty($input['https'])) {
return $input['https']; // https
}
}
请注意一些其他的问题,那就是通过 URI 模式
访问资源和通过 PHP CLI
模式访问资源,服务器参数是有好多不同的
URI 模式有 $_SERVER 中的N多参数, PHP CLI 模式并没有相关参数,如果你的项目中既用到了 URI 模式访问资源也用到了 PHP CLI 模式来执行一些操作,那你区分这块就要下点功夫来调整细节问题。
判断是否为 CLI
模式
function is_cli ()
{
return preg_match("/cli/i", php_sapi_name()) ? true : false;
}
那上面也说过2种设置参数的方法了,cli模式
中并不会有 $_SERVER 参数,所以选择一种加参数的方式就显得格外重要了,可以加在 php.ini
或者 php-fpm.conf
中,通过 get_cfg_var()
来获取你的设置并加载相关配置文件。