HortusFox 6.4 配置参数详解

HortusFox 6.4 三层配置体系实测详解:.env 六段参数逐项语义与 dotenv 解析规则实测、app/config 文件组、管理后台 AppModel 五十余项工作区设置与出厂数据库默认值、配置生效方式与配置视角排障实录。

HortusFoxPHP 编程园艺管理Ubuntu24.042026/10/28

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/*.phprequire 时即取,随代码生效命令注册、路由、照片缩放、版本号、事件
工作区设置数据库 AppModel 表(管理后台编辑)每次请求按需查询界面开关、聊天、定时任务口令、外部 API key

两个关键的覆盖关系决定了排障方向:

  1. SMTP 参数有两处:.env 的 SMTP_* 段是兜底初始值;管理后台 AppModel 的 smtp_* 段在发信前通过 app_mail_config()(app/helper/AppHelper.php)整体覆写 $_ENV,运行期以管理后台为准(详见第七节)。
  2. 界面语言有三层:用户个人资料语言 > 工作区语言(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_NAMEHortusFox应用名,界面标题等品牌文案的数据源
APP_VERSION6.4产品版本号;不要手改——app/config/version.php(return '6.4';)与之成对,升级时由 php asatru migrate:version 自动同步两处(见《HortusFox 6.4 常用 CLI 命令与工具详解》)
APP_AUTHORDaniel Brendel作者署名,product:info 输出
APP_CONTACTdaniel@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_ENABLEtrue会话总开关;框架启动时(bootstrap.php 第 73 行)据此初始化会话
SESSION_DURATION32532000会话有效期(秒),同时写入 session.cookie_lifetime 与 session.gc_maxlifetime 两个 ini(第 74-76 行)。32532000 秒 ≈ 376.5 天,即"登录态约一年"
SESSION_NAMEnull自定义会话 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_ENABLEtrue数据库总开关。为 false 时连接层直接跳过,所有依赖库的功能不可用;CLI 侧所有迁移类命令也会被 validate_database_enabled() 拦截
DB_HOSTlocalhost主机名;本机走 socket 或 TCP 取决于 MariaDB 配置
DB_USER / DB_PASSWORDhortusfox / q1w2e3r4第三节部署时创建的专用账号(口令请替换为自己的强口令)
DB_PORT3306端口
DB_DATABASEhortusfox库名;部署实录实测共 27 张表
DB_DRIVERmysql只支持 mysql(vendor/.../src/database.php 第 1218 行对其他值直接抛出 Database driver X is not supported)。MariaDB 走的也是 mysql 驱动,填 mariadb 反而报错
DB_CHARSETutf8mb4连接字符集;与建库时 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_AUTHtrue是否启用 SMTP 认证
SMTP_FROMNAME / SMTP_FROMADDRESSTest / test@domain.tld发件人名与地址;密码重置、用户邀请、逾期提醒邮件的发件身份
SMTP_HOST空服务器地址;留空则邮件功能整体不可用
SMTP_PORT587端口
SMTP_USERNAME / SMTP_PASSWORD空认证凭据
SMTP_ENCRYPTIONtls加密方式: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.phpCLI 命令注册表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 基本信息

字段库默认说明
workspaceMy workspace工作区名(实测值:HortusFox 工作区),页面标题与分享卡片用它
languageen工作区语言,语言优先级第二层(3.4 节)
timezoneNULL工作区时区(实测值:Asia/Shanghai)
date_format / time_formatY-m-d / H:i:s界面日期/时间展示格式,PHP date() 语法

10.2 功能开关

字段库默认说明
tasks_enable / inventory_enable / calendar_enable1/1/1任务/库存/日历三大模块开关,关掉即从界面隐藏
history_enable / history_name1 / History历史记录模块开关与菜单名
scroller1列表滚动加载
quick_add0快捷添加入口
allow_custom_attributes0允许用户自定义植物属性
system_message_plant_log1群聊系统消息自动写入植物日志

10.3 聊天组

字段库默认说明
chat_enable1群聊总开关
chat_timelimit5消息轮询间隔(秒)
chat_showusers1显示在线用户
chat_indicator1输入中指示器
chat_system1系统消息(如"XX 添加了植物")入聊天流

10.4 界面与媒体

字段库默认说明
pwa_enable0PWA(渐进式 Web 应用)支持
enable_media_share0媒体外链分享
custom_media_share_hostNULL自定义分享域名
custom_head_code空注入到页面 <head> 的自定义代码(统计脚本、字体等)
overlay_alphaNULL界面遮罩透明度

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_auth1对应 SMTP_AUTH
smtp_fromname / smtp_fromaddressNULL发件人(实测值:HortusFox / admin@hortusfox.local)
smtp_host / smtp_portNULL / 587服务器(实测值:127.0.0.1:1025,本机邮件中继)
smtp_username / smtp_passwordNULL认证凭据
smtp_encryptiontlstls / smtps / none(none 仅此处合法,见第七节)
mail_rp_addressNULL回复(Reply-To)地址

10.7 天气预报组(OpenWeatherMap)

字段库默认说明
owm_enable0天气功能开关
owm_api_keyNULLOpenWeatherMap API key(A1 介绍篇提到的可选外部服务在此接入)
owm_latitude / owm_longitudeNULL经纬度,决定预报地点
owm_unittypedefault单位制(default 开尔文/metric 摄氏/imperial 华氏)
owm_cache300天气缓存秒数,默认 5 分钟,避免打爆免费配额

10.8 植物识别组(Pl@ntNet)

字段库默认说明
plantrec_enable0识别功能开关
plantrec_apikeyNULLPl@ntNet API key
plantrec_quickscan0快捷扫描入口

10.9 备份组

字段库默认说明
auto_backup0自动备份开关(实测值:1,配合 POST /cronjob/backup/auto 定时归档)
backup_pathNULL备份归档目录;留空用默认 public/backup/

手动备份/恢复的命令行用法(backup:export / backup:import)见《HortusFox 6.4 常用 CLI 命令与工具详解》。

10.10 认证代理组(外部认证)

字段库默认说明
auth_proxy_enable0启用反向代理认证(如 Authelia/oauth2-proxy 在前置层完成认证)
auth_proxy_header_email / auth_proxy_header_usernameNULL传递用户邮箱/用户名的 HTTP 头名
auth_proxy_sign_up0首次登录自动注册
auth_proxy_whitelistNULL绕过代理认证的白名单路径
auth_proxy_hide_logout0隐藏登出按钮(登出由前置代理处理)

💡 技术拓展:认证代理(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 命令与工具详解》(本专栏)。