HortusFox 6.4 配置参数详解
HortusFox 6.4 三层配置体系实测详解:.env 六段参数逐项语义与 dotenv 解析规则实测、app/config 文件组、管理后台 AppModel 五十余项工作区设置与出厂数据库默认值、配置生效方式与配置视角排障实录。
HortusFox 6.4 配置参数详解
本文全部参数与行为均在实测环境逐项验证并取自真实回显:Ubuntu 24.04.5 LTS(noble)、HortusFox v6.4(截至 2026-10-28 的最新稳定版,见 danielbrendel/hortusfox-web 仓库 Releases)、PHP 8.3.6、MariaDB 11.4.13。示例管理员账号 admin / q1w2e3r4,示例服务器以 IP 10.89.73.10 直连。部署全流程见 《HortusFox 安装部署指南》。
项目定位与技术栈背景见 《HortusFox 介绍与选型指南》。部署完成后,HortusFox 的所有行为调整——界面语言、邮件通道、数据库连接、照片处理、定时任务、外部服务接入——都落在本文要讲清的三层配置体系里。每个参数的语义、取值、消费代码位置与生效方式,均以实测服务器上的实际源码与数据库状态为准,不照抄官方文档。
一、三层配置体系总览
HortusFox 的配置不是一张大表,而是三个层面各司其职:
| 层面 | 位置 | 读取时机 | 典型内容 |
|---|---|---|---|
| 环境参数 | 项目根目录 .env(模板 .env.example) | 每次 HTTP 请求(Web 入口 bootstrap.php 第 52 行以绝对路径 ASATRU_APP_ROOT . '/.env' 解析)与每个 CLI 进程启动时 | 应用名、数据库连接、SMTP、会话、日志 |
| 框架配置组 | app/config/*.php | require 时即取,随代码生效 | 命令注册、路由、照片缩放、版本号、事件 |
| 工作区设置 | 数据库 AppModel 表(管理后台编辑) | 每次请求按需查询 | 界面开关、聊天、定时任务口令、外部 API key |
两个关键的覆盖关系决定了排障方向:
- SMTP 参数有两处:
.env的SMTP_*段是兜底初始值;管理后台 AppModel 的smtp_*段在发信前通过app_mail_config()(app/helper/AppHelper.php)整体覆写$_ENV,运行期以管理后台为准(详见第七节)。 - 界面语言有三层:用户个人资料语言 > 工作区语言(AppModel.language)>
.env的APP_LANG兜底(app/controller/_base.php 第 63 行,详见 3.4 节)。
其余 .env 参数没有"双份"问题,改哪份就是哪份。
二、.env 解析规则
.env 由框架自带的 dotenv 组件(vendor/danielbrendel/asatru-php-framework/src/dotenv.php)解析,规则比通用 dotenv 更简单:
- 每行一条
name=value,#开头为注释,空行跳过; - 值无需强制引号:双引号包裹的按字符串取值;
null字面量解析为 PHP null;数字自动转 int/float;true/on/yes转 bool true;false/off/no转 bool false;其余按原样字符串; - 支持
${VARNAME}引用同文件中已解析的变量做插值; - 代码通过
env('KEY', $fallback)读取,键不存在时返回 fallback。
实测验证(在服务器上用框架解析器解析一段测试配置并 var_dump):
T_INT=3306 → int(3306)
T_FLOAT=1.0 → float(1)
T_TRUE=true → bool(true)
T_YES=yes → bool(true)
T_NULL=null → NULL
T_STR="utf8mb4" → string(7) "utf8mb4"
T_RAW=hello → string(5) "hello"
T_REF=${T_RAW}-world → string(11) "hello-world"
T_MISSING(未定义) → fallback 值 "fb"
注意 1.0 被解析成 float(1)——浮点写法保留但数值上无小数差异,对缩放因子这类参数没有实际影响。
两条书写红线:含空格的值必须用双引号(如 APP_NAME="My App"),且双引号必须成对闭合(解析器检测到不闭合直接报语法错误);字符串里想表达字面量 null/true/false 时也要加引号,否则会被类型推导吃掉。
三、应用基础参数(APP_*)
.env 模板的应用段共 14 个键:
# App settings
APP_NAME="HortusFox"
APP_VERSION="6.4"
APP_AUTHOR="Daniel Brendel"
APP_CONTACT="daniel@danielbrendel.com"
APP_DEBUG=true
APP_BASEDIR=""
APP_LANG="en"
APP_WORKSPACE="My workspace"
APP_OVERDUETASK_HOURS=10
APP_CRONJOB_MAILLIMIT=5
APP_GITHUB_URL="https://github.com/danielbrendel/hortusfox-web"
APP_SERVICE_URL="https://www.hortusfox.com"
APP_GITHUB_SPONSOR="https://github.com/sponsors/danielbrendel"
APP_DONATION_KOFI="https://ko-fi.com/danielbrendel"
3.1 APP_NAME / APP_VERSION / APP_AUTHOR / APP_CONTACT
| 键 | 默认值 | 语义与消费点 |
|---|---|---|
| APP_NAME | HortusFox | 应用名,界面标题等品牌文案的数据源 |
| APP_VERSION | 6.4 | 产品版本号;不要手改——app/config/version.php(return '6.4';)与之成对,升级时由 php asatru migrate:version 自动同步两处(见《HortusFox 6.4 常用 CLI 命令与工具详解》) |
| APP_AUTHOR | Daniel Brendel | 作者署名,product:info 输出 |
| APP_CONTACT | daniel@danielbrendel.com | 项目联系邮箱;变更用 php asatru migrate:email <新邮箱>,它会同步替换 6 个文件中的旧地址 |
3.2 APP_DEBUG
调试总开关,影响面比名字大得多:
- CLI 门禁:asatru 命令行工具只在调试模式下工作。实测把
APP_DEBUG改为 false 后执行 CLI:
$ php asatru product:version
CLI tool is only available in debug mode
- product:info 的标题行会带上 Debug 字样(实测
HortusFox v6.4 Debug)。
生产环境若想关掉调试,就必须接受 CLI 不可用(备份、迁移、主题管理都走 CLI),因此官方模板默认 true 是有意为之;建议保持 true,改用 Web 服务器层控制暴露面。
3.3 APP_BASEDIR
子路径部署前缀。默认空串表示部署在域名根;若应用挂在 https://example.com/hortusfox/ 下,填 hortusfox(不带斜杠),框架在构造跳转头时会拼上该前缀(vendor/danielbrendel/asatru-php-framework/src/view.php 第 708 行 header('Location: ' . ... . $this->resource))。实测环境部署在根路径,保持 ""。
3.4 APP_LANG
界面语言的兜底默认值,实际解析优先级为:用户个人资料里的语言(UserModel.lang,个人资料页可改)→ 工作区语言(AppModel.language,管理后台可改)→ APP_LANG。实测项目自带 12 种语言包(app/lang 目录):da de en es fr hu it nl no pl pt-br ru。中文不在官方语言包内,填 zh 会回退到英文;想要中文界面只能自行翻译语言包(复制 app/lang/en 为 app/lang/zh 逐条翻译,属于二次开发范畴)。B1 部署实录中登录响应的 Set-Cookie: COOKIE_LOCALE=en 即语言 cookie 的落点。
3.5 APP_WORKSPACE
实测修正一个普遍误解:这个键只被安装器消费(public/install/index.php 与 scripts/install.dnys 在安装时把它写进 .env 并作为工作区初始数据),运行期的工作区名来自数据库 AppModel.workspace 字段,改 .env 里的 APP_WORKSPACE 不会影响已初始化的系统。实测环境的证据:.env 中是 APP_WORKSPACE="My workspace",而登录后页面标题与管理后台显示的是 HortusFox 工作区(AppModel 实际值)。改名请走管理后台,详见第十节。
3.6 APP_OVERDUETASK_HOURS / APP_CRONJOB_MAILLIMIT
APP_OVERDUETASK_HOURS:任务判定"即将逾期"的小时窗口。代码默认 5(app/models/TasksModel.php 第 249 行strtotime('+' . env('APP_OVERDUETASK_HOURS', 5) . ' hours', ...)),.env模板给的是 10——即距截止 10 小时内的任务在逾期提醒中会被标出。按自家浇水节奏调整即可。APP_CRONJOB_MAILLIMIT:单次定时任务执行最多发送的提醒邮件条数,防止任务大量逾期时邮件轰炸。消费点在 TasksModel 第 263/289/316 行(逾期/明日到期/周期任务三类提醒)与 CalendarModel 第 150 行(日历提醒)。代码默认 5。
这两个参数都只在定时任务链路上起作用,而定时任务依赖外部周期调用 cronjob 端点——systemd timer 托管方案见《HortusFox 安装部署指南》第十一节。
3.7 APP_GITHUB_URL / APP_SERVICE_URL / APP_GITHUB_SPONSOR / APP_DONATION_KOFI
四个"官方链接"参数,三处消费:product:info 的输出(GitHub/Service/Sponsoring/Donation 四行)、aquashell:config 生成的安装脚本配置、以及APP_SERVICE_URL 兼任主题商店的下载源——theme:install <name> 实际请求 APP_SERVICE_URL/downloads/<主题名>.zip。因此若把 APP_SERVICE_URL 指到自建镜像或内网地址,主题在线安装也会跟着指向那里。
四、会话参数(SESSION_*)
# Session
SESSION_ENABLE=true
SESSION_DURATION=32532000
SESSION_NAME=null
| 键 | 默认值 | 语义 |
|---|---|---|
| SESSION_ENABLE | true | 会话总开关;框架启动时(bootstrap.php 第 73 行)据此初始化会话 |
| SESSION_DURATION | 32532000 | 会话有效期(秒),同时写入 session.cookie_lifetime 与 session.gc_maxlifetime 两个 ini(第 74-76 行)。32532000 秒 ≈ 376.5 天,即"登录态约一年" |
| SESSION_NAME | null | 自定义会话 cookie 名;为 null/空时用 PHP 默认名。实测登录响应的 cookie 名是默认的 PHPSESSID |
要缩短登录有效期(比如团队场景改成按工作日过期),把 SESSION_DURATION 改成目标秒数即可,如 86400 为一天;该值必须是纯数字,解析器会按 int 处理。
五、照片缩放参数(PHOTO_RESIZE_FACTOR_*)
# Photo resize factors
PHOTO_RESIZE_FACTOR_DEFAULT=1.0
PHOTO_RESIZE_FACTOR_1=0.5
PHOTO_RESIZE_FACTOR_2=0.4
PHOTO_RESIZE_FACTOR_3=0.4
PHOTO_RESIZE_FACTOR_4=0.3
PHOTO_RESIZE_FACTOR_5=0.2
植物照片是 HortusFox 的存储大户,这组参数控制上传照片生成多档缩放副本的比例。app/config/resize.php 把六个键映射为 default/factor_1..factor_5,上传处理时按档位取用(app/modules/UtilsModule.php 第 163-175 行):DEFAULT 是原图比例(1.0 不缩),1~5 档依次生成 50%、40%、40%、30%、20% 尺寸的副本,界面按展示场景选档加载。手机随手拍动辄 5MB+,五档副本能把列表页流量压到原图的两成以下;实测环境保持默认。若磁盘紧张可整体下调档位比例。
六、数据库参数(DB_*)
# Database settings
DB_ENABLE=true
DB_HOST=localhost
DB_USER=hortusfox
DB_PASSWORD="q1w2e3r4"
DB_PORT=3306
DB_DATABASE=hortusfox
DB_DRIVER=mysql
DB_CHARSET="utf8mb4"
| 键 | 实测值 | 语义 |
|---|---|---|
| DB_ENABLE | true | 数据库总开关。为 false 时连接层直接跳过,所有依赖库的功能不可用;CLI 侧所有迁移类命令也会被 validate_database_enabled() 拦截 |
| DB_HOST | localhost | 主机名;本机走 socket 或 TCP 取决于 MariaDB 配置 |
| DB_USER / DB_PASSWORD | hortusfox / q1w2e3r4 | 第三节部署时创建的专用账号(口令请替换为自己的强口令) |
| DB_PORT | 3306 | 端口 |
| DB_DATABASE | hortusfox | 库名;部署实录实测共 27 张表 |
| DB_DRIVER | mysql | 只支持 mysql(vendor/.../src/database.php 第 1218 行对其他值直接抛出 Database driver X is not supported)。MariaDB 走的也是 mysql 驱动,填 mariadb 反而报错 |
| DB_CHARSET | utf8mb4 | 连接字符集;与建库时 CHARACTER SET utf8mb4 保持一致 |
💡 技术拓展:为什么是 utf8mb4 而不是 utf8?MySQL/MariaDB 的
utf8历史上是三字节实现的截断版,存不下 emoji 等增补平面字符;utf8mb4才是完整四字节 UTF-8。植物名、笔记里出现 🌵🌿 这类 emoji 是常态,用 utf8 会在写入时被截断报错,所以模板固定 utf8mb4,建库语句(见部署指南第三节)也必须一致。
迁移建表用 php asatru migrate:fresh(全量重建,仅初始化时用),增量迁移用 migrate:list/migrate:upgrade——命令细节见《HortusFox 6.4 常用 CLI 命令与工具详解》。
七、邮件 SMTP 参数
.env 的 SMTP 段共 8 键:
# SMTP settings
SMTP_AUTH=true
SMTP_FROMNAME="Test"
SMTP_FROMADDRESS="test@domain.tld"
SMTP_HOST=""
SMTP_PORT=587
SMTP_USERNAME=""
SMTP_PASSWORD=""
SMTP_ENCRYPTION=tls
| 键 | 默认值 | 语义 |
|---|---|---|
| SMTP_AUTH | true | 是否启用 SMTP 认证 |
| SMTP_FROMNAME / SMTP_FROMADDRESS | Test / test@domain.tld | 发件人名与地址;密码重置、用户邀请、逾期提醒邮件的发件身份 |
| SMTP_HOST | 空 | 服务器地址;留空则邮件功能整体不可用 |
| SMTP_PORT | 587 | 端口 |
| SMTP_USERNAME / SMTP_PASSWORD | 空 | 认证凭据 |
| SMTP_ENCRYPTION | tls | 加密方式:tls(STARTTLS,通常配 587)或 smtps(SMTPS/隐式 TLS,通常配 465);填其他值发信时直接抛 Unknown encryption type |
关键机制——两处 SMTP 配置的覆盖关系:框架发信前,应用层的 app_mail_config()(app/helper/AppHelper.php 第 49-61 行)会用管理后台的工作区 SMTP 设置整体覆写 $_ENV 里的 8 个 SMTP 键:
function app_mail_config()
{
$_ENV['SMTP_AUTH'] = app('smtp_enable_auth');
$_ENV['SMTP_FROMNAME'] = app('smtp_fromname');
$_ENV['SMTP_FROMADDRESS'] = app('smtp_fromaddress');
$_ENV['SMTP_HOST'] = app('smtp_host');
// ...SMTP_PORT/USERNAME/PASSWORD/ENCRYPTION 同理
}
所以:配了管理后台的 SMTP(推荐),.env 段就只是初始兜底;只改 .env 不动管理后台是不生效的。实测环境即走了管理后台路线:smtp_host=127.0.0.1、smtp_port=1025、smtp_encryption=none(本机邮件中继),此时 .env 里的 tls/587 完全不参与。另外管理后台的加密选项比 .env 多一个 none(明文,配合内网中继),由 mail_properties() 在发信时转成"无加密"处理——这个值只在接受后台输入的路径上合法,直接写 .env 的 SMTP_ENCRYPTION=none 仍会抛未知加密类型。
💡 技术拓展:STARTTLS 与 SMTPS 的区别?STARTTLS(
.env的tls)先以明文 587 端口握手、再升级为 TLS 加密,是现代邮件服务商的主流;SMTPS(smtps)从连接建立起就是 TLS(465 端口,历史上非标但广泛使用)。内网自建中继(如本机 Mailpit/MailHog 类工具)两者都不用,选后台的none。对外发信按服务商文档二选一,配错端口与加密方式的组合是最常见的发信失败原因。
SMTP 配好后可用管理后台的"发送测试邮件"按钮(POST /admin/mail/test 路由)直接自测,不必等真实提醒触发。
八、日志参数(LOG_ENABLE)
# Logging
LOG_ENABLE=true
日志总开关,消费点在框架 logger 组件(vendor/.../src/logger.php 第 72 行)。开启后框架日志写入 app/logs/logfile_<日期>.txt,实测文件内容样例:
$ tail -3 app/logs/logfile_2026-10-28.txt
[2026-10-28 05:27:20 pm][Header] Asatru PHP log on 2026-10-28 09:27:20 am
日志按天分文件、自动落盘,无需轮转配置;排障时先看这里和 Web 服务器错误日志。关闭(false)后日志静默,生产不建议关。
九、app/config 配置文件组
app/config/ 下六个 PHP 配置文件,改动随代码部署生效(PHP 每请求重新加载):
| 文件 | 内容 | 说明 |
|---|---|---|
| autoload.php | 类自动加载映射 | 新增自研类目录时改 |
| commands.php | CLI 命令注册表 | 15 条应用命令 [命令名, 描述, 处理器类],自定义命令在此注册(详见 CLI 详解篇) |
| events.php | 事件监听注册 | 框架事件机制挂载点 |
| resize.php | 照片缩放映射 | 读第五节的 PHOTO_RESIZE_FACTOR_* |
| routes.php | 全部 177 条 HTTP 路由 | routes:list 命令可打印(详见 CLI 详解篇) |
| version.php | 产品版本号 | return '6.4';,与 .env APP_VERSION 成对,由 migrate:version 维护 |
这组文件是"代码的一部分",随 git 走;而 .env 与数据库设置是"环境的一部分",随服务器走。升级拉新代码时 git 不会动你的 .env,但 app/config/*.php 会被上游更新——这正是版本参数需要 migrate 命令同步的原因。
十、管理后台工作区设置(AppModel)
第三层配置是数据库 AppModel 表的单行记录(id=1),通过管理后台 Web 界面编辑:管理员登录后访问 /admin。它的字段就是 HortusFox 的"运行时设置面板",以下按功能分组列全 50 余项,"库默认"为实测 SHOW COLUMNS 的出厂默认值,"实测值"标注了实验环境与默认不同的项。
10.1 基本信息
| 字段 | 库默认 | 说明 |
|---|---|---|
| workspace | My workspace | 工作区名(实测值:HortusFox 工作区),页面标题与分享卡片用它 |
| language | en | 工作区语言,语言优先级第二层(3.4 节) |
| timezone | NULL | 工作区时区(实测值:Asia/Shanghai) |
| date_format / time_format | Y-m-d / H:i:s | 界面日期/时间展示格式,PHP date() 语法 |
10.2 功能开关
| 字段 | 库默认 | 说明 |
|---|---|---|
| tasks_enable / inventory_enable / calendar_enable | 1/1/1 | 任务/库存/日历三大模块开关,关掉即从界面隐藏 |
| history_enable / history_name | 1 / History | 历史记录模块开关与菜单名 |
| scroller | 1 | 列表滚动加载 |
| quick_add | 0 | 快捷添加入口 |
| allow_custom_attributes | 0 | 允许用户自定义植物属性 |
| system_message_plant_log | 1 | 群聊系统消息自动写入植物日志 |
10.3 聊天组
| 字段 | 库默认 | 说明 |
|---|---|---|
| chat_enable | 1 | 群聊总开关 |
| chat_timelimit | 5 | 消息轮询间隔(秒) |
| chat_showusers | 1 | 显示在线用户 |
| chat_indicator | 1 | 输入中指示器 |
| chat_system | 1 | 系统消息(如"XX 添加了植物")入聊天流 |
10.4 界面与媒体
| 字段 | 库默认 | 说明 |
|---|---|---|
| pwa_enable | 0 | PWA(渐进式 Web 应用)支持 |
| enable_media_share | 0 | 媒体外链分享 |
| custom_media_share_host | NULL | 自定义分享域名 |
| custom_head_code | 空 | 注入到页面 <head> 的自定义代码(统计脚本、字体等) |
| overlay_alpha | NULL | 界面遮罩透明度 |
10.5 定时任务
| 字段 | 库默认 | 说明 |
|---|---|---|
| cronjob_pw | 空 | cronjob 端点口令(实测值:q1w2e3r4),调用五个 cronjob HTTP 端点时以 cronpw 参数携带;口令在后台可一键重新生成 |
五个端点(POST /cronjob/tasks/overdue、tasks/tomorrow、tasks/recurring、calendar/reminder、backup/auto)的用途、频率建议与 systemd timer 托管全流程见《HortusFox 安装部署指南》第十一节。
10.6 SMTP 覆盖组(优先于 .env)
| 字段 | 库默认 | 说明 |
|---|---|---|
| smtp_enable_auth | 1 | 对应 SMTP_AUTH |
| smtp_fromname / smtp_fromaddress | NULL | 发件人(实测值:HortusFox / admin@hortusfox.local) |
| smtp_host / smtp_port | NULL / 587 | 服务器(实测值:127.0.0.1:1025,本机邮件中继) |
| smtp_username / smtp_password | NULL | 认证凭据 |
| smtp_encryption | tls | tls / smtps / none(none 仅此处合法,见第七节) |
| mail_rp_address | NULL | 回复(Reply-To)地址 |
10.7 天气预报组(OpenWeatherMap)
| 字段 | 库默认 | 说明 |
|---|---|---|
| owm_enable | 0 | 天气功能开关 |
| owm_api_key | NULL | OpenWeatherMap API key(A1 介绍篇提到的可选外部服务在此接入) |
| owm_latitude / owm_longitude | NULL | 经纬度,决定预报地点 |
| owm_unittype | default | 单位制(default 开尔文/metric 摄氏/imperial 华氏) |
| owm_cache | 300 | 天气缓存秒数,默认 5 分钟,避免打爆免费配额 |
10.8 植物识别组(Pl@ntNet)
| 字段 | 库默认 | 说明 |
|---|---|---|
| plantrec_enable | 0 | 识别功能开关 |
| plantrec_apikey | NULL | Pl@ntNet API key |
| plantrec_quickscan | 0 | 快捷扫描入口 |
10.9 备份组
| 字段 | 库默认 | 说明 |
|---|---|---|
| auto_backup | 0 | 自动备份开关(实测值:1,配合 POST /cronjob/backup/auto 定时归档) |
| backup_path | NULL | 备份归档目录;留空用默认 public/backup/ |
手动备份/恢复的命令行用法(backup:export / backup:import)见《HortusFox 6.4 常用 CLI 命令与工具详解》。
10.10 认证代理组(外部认证)
| 字段 | 库默认 | 说明 |
|---|---|---|
| auth_proxy_enable | 0 | 启用反向代理认证(如 Authelia/oauth2-proxy 在前置层完成认证) |
| auth_proxy_header_email / auth_proxy_header_username | NULL | 传递用户邮箱/用户名的 HTTP 头名 |
| auth_proxy_sign_up | 0 | 首次登录自动注册 |
| auth_proxy_whitelist | NULL | 绕过代理认证的白名单路径 |
| auth_proxy_hide_logout | 0 | 隐藏登出按钮(登出由前置代理处理) |
💡 技术拓展:认证代理(auth proxy)与本地认证的关系?开启后 HortusFox 不再自己管登录页,而是信任前置网关注入的头字段——这是自托管圈常见的"统一入口"玩法:所有应用都挂在 Authelia 之类的门户后面,一次登录处处通行。家庭单用户场景收益不大,多服务 homelab 才值得配。
十一、配置修改与生效方式
三层配置的生效速度不同,改错地方是"改了没反应"的根源:
| 改动 | 生效时机 | 要不要重启 |
|---|---|---|
.env | 下一次 HTTP 请求即生效(每请求重新解析)、下一个 CLI 进程即生效 | 否。PHP-FPM 不缓存 .env,无需 systemctl reload |
| app/config/*.php | 随下一次请求/进程生效 | 否 |
| AppModel(后台保存) | 立即(直接落库,每请求现查) | 否 |
| PHP 自身参数(upload_max_filesize 等) | 需 systemctl restart php8.3-fpm | 是(见部署指南第八节) |
一个实测可验证的对照:改 .env 的 APP_VERSION 后跑 php asatru product:version 立即显示新值;改管理后台的 workspace 名,刷新页面标题立即变。全程没有重启动作。
十二、排障实录(配置视角)
1. CLI 全部命令报 "CLI tool is only available in debug mode"。
实测把 APP_DEBUG=true 改为 false 即复现。CLI 门禁读的就是这个键。生产环境必须关调试的话,要接受 CLI 不可用;更好的做法是保持 true 并在网络层收紧暴露。另一个同报错场景:在项目根目录之外执行 php /var/www/hortusfox/asatru——CLI 入口用相对路径 file_exists('.env') 找配置,工作目录不对就等于调试未开(详见部署指南排障实录第 1 条)。
2. 改了 .env 的 APP_WORKSPACE,界面工作区名纹丝不动。
运行期工作区名读 AppModel.workspace(数据库),不读 .env。去管理后台改。这个键在 .env.example 里的存在感来自安装器(安装时用它生成初始数据),属于"看得到但运行期不管事"的历史遗留。
3. SMTP 明明配好了,测试邮件还是发不出去。
先分清改的是哪一层:.env SMTP 段会被管理后台的 smtp_* 段在发信前整体覆写(第七节的 app_mail_config 机制)。实测环境曾出现 .env 写 tls:587、后台写 none:1025,实际发信永远走后台值。排查顺序:管理后台 SMTP 段 → .env 段 → 邮件中继日志。另外 .env 的 SMTP_ENCRYPTION 只认 tls/smtps,none 只能在后台选。
4. DB_DRIVER 改成 mariadb 后迁移报错。
源码只认 mysql 一个值,Database driver mariadb is not supported。MariaDB 11.4 用的就是 mysql 协议驱动,保持 mysql 不动。
5. 想在 .env 里存字面量 "null" 或含空格的值,行为诡异。
类型推导是全局的:SESSION_NAME=null 被解析成 PHP null(而不是字符串"null"),APP_NAME=My App 不加引号会把空格后内容丢弃(按裸 token 解析)。规则记三条:含空格必加双引号、想当字符串用的 null/true/false 也加引号、数值与布尔裸写即可。
十三、小结
HortusFox 的配置面可以压缩成三句话:环境层 .env 管进程启动参数(数据库、SMTP 兜底、会话、日志),配置组 app/config 管代码级注册(路由、命令、缩放、版本),数据库层 AppModel 管运行期工作区行为(功能开关、外部服务 key、SMTP 实际生效值)。踩坑几乎都出在"改错层"上——改 .env 的 SMTP 不看后台覆盖、改 .env 的 APP_WORKSPACE 期待界面生效,都是典型。三层各自"即改即生效、无需重启"是这套 PHP 应用的省心之处。
配套阅读:部署链路与 systemd 托管见 《HortusFox 安装部署指南》;本文第九、十节涉及的 31 条 CLI 命令(迁移、备份、主题、脚手架)逐条实测详解见《HortusFox 6.4 常用 CLI 命令与工具详解》(本专栏)。