/
/ alt
* 变成空白,页面连名字都没有。
* 这里显式写出来,而不是指望 setting() 全局回退 —— 那正是「副标题删不掉」的病根。
*/
function site_name(): string
{
$n = setting('site_name');
return $n !== '' ? $n : APP_NAME;
}
/**
* 设置表缓存(可失效)。
*
* ⚠️ 为什么必须能失效:这个缓存只在**首次读取**时查库,之后整进程复用。
* 后台「保存设置 → 重定向」是两次请求,所以以前没暴露问题;但只要有**同一次请求里
* 先写设置、再读回来**的路径(上传站点图标就是:写完马上要用新键拼 URL),
* 就会读到写之前的旧值 —— 表现为「上传成功但图标没变」。
* 任何写入设置的地方,写完都要调 settings_reload()。
*/
function settings_cache(bool $reload = false): array
{
static $cache = null;
if ($cache === null || $reload) {
$cache = [];
try {
foreach (db()->query('SELECT k, v FROM settings') as $row) {
$cache[$row['k']] = $row['v'];
}
} catch (Throwable $e) {
$cache = [];
}
}
return $cache;
}
/** 写入设置后调用,让本次请求后续的 setting() 读到新值 */
function settings_reload(): void
{
settings_cache(true);
}
/**
* 读取设置项。
*
* ⚠️ 空串是一等公民:**只有「这一行不存在」才回退 $default**。
* 曾经这里写的是 `$cache[$key] !== ''`,把「用户主动清空」和「从未配置过」当成一回事,
* 于是后台删掉副标题后前台照样显示默认的「个人网站导航」——删不掉。
* 需要「空则回退」的设置请在自己的读取点显式写明(如 site_name()),
* 不要把这个语义塞回函数里。
*/
function setting(string $key, string $default = ''): string
{
$cache = settings_cache();
return array_key_exists($key, $cache) ? $cache[$key] : $default;
}