apache的servername不可直接用于运行时判断,但可通过setenvif基于host头匹配域名动态设环境变量(如env_type=prod),再配合require、rewritecond或customlog实现按域控制访问、跳转与日志隔离。

Apache 的 ServerName 本身是静态配置项,不能直接参与运行时逻辑判断;但你可以用 SetEnv 和 SetEnvIf 在虚拟主机内基于 ServerName 或其衍生特征(如域名、子域)动态设置环境变量,再用于后续控制——这相当于“模拟局部变量”的条件逻辑。
用 SetEnvIf 根据 ServerName 自动设变量
这是最常用也最可靠的方式。Apache 不允许在 ServerName 行里写表达式,但 SetEnvIf 可以匹配 Host 请求头(通常和 ServerName 一致),实现按域名区分行为:
SetEnvIf Host ^www\.example\.com$ ENV_TYPE=prodSetEnvIf Host ^dev\.example\.com$ ENV_TYPE=devSetEnvIf Host ^staging\.example\.com$ ENV_TYPE=stage
这些变量只对匹配该 Host 的请求生效,作用域限于当前虚拟主机或目录,无需担心跨站污染。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
配合 Require 或 RewriteCond 做权限或跳转控制
设好变量后,不能“直接 if 判断”,必须通过 Apache 的条件指令来消费:
- 限制访问:
Require env ENV_TYPE+Require expr %{ENV:ENV_TYPE} == 'prod' - 重定向开发域名:
RewriteCond %{ENV:ENV_TYPE} =dev→RewriteRule ^(.*)$ https://dev-backend.example.com$1 [P] - 日志隔离:
CustomLog logs/access_dev.log common env=ENV_TYPE
避免常见陷阱:变量不是全局,也不自动继承
SetEnv 和 SetEnvIf 设置的变量不会自动传给 PHP 的 $_ENV(除非显式启用 variables_order),也不会影响子目录外的配置。注意几点:
- 若在
.htaccess中用SetEnvIf,需确保AllowOverride All且mod_setenvif已加载 -
SetEnv是无条件赋值,SetEnvIf才是带条件的——别误用SetEnv替代判断逻辑 - 变量名不要含点号或连字符(如
APP.VERSION),Apache 解析可能出错,建议用下划线APP_VERSION
进阶:用 SetEnvIf 提取子域作为可复用标识
比如统一处理多语言子域 fr.example.com、de.example.com,可提取语言码供后端读取:
SetEnvIf Host "^([a-z]{2})\.example\.com$" LANG_CODE=$1- PHP 中用
getenv('LANG_CODE')就能拿到fr或de - 配合
ProxyPass转发时,还可加请求头:RequestHeader set X-Language %{LANG_CODE}e










