Files

94 lines
4.4 KiB
PHP
Raw Permalink Normal View History

<?php
// ============================================
// 文件: config.php
// 说明: 应用引导入口。负责错误报告、会话、路径常量、上传目录,
// 并加载 lib/ 下的各功能模块,最后初始化数据库。
// 所有页面统一通过 require_once 'config.php' 引入本文件。
// ============================================
2026-10-31 21:35:41 +08:00
// 错误报告策略。
//
// 关键:PHP 的警告/弃用提示是**直接写进响应体**的。对返回 JSON 的接口
// (fetch_movie.php、storage_api.php 等)来说,一条 Warning 插在 JSON 前面
// 就会让前端 JSON.parse 失败,表现为「功能静默失灵」——联想下拉空着、
// 存储测试报连接失败,都可能是这个原因,而接口本身其实是好的。
//
// 本项目踩过:PHP 8.5 把 curl_close() 标为 deprecated,一行提示就把
// 「电影名联想」整个搞挂了(接口返回的 JSON 完全正确,只是前面多了警告)。
//
// 因此:
// - 永远不把错误显示给浏览器(display_errors=0);
// - 仍然记录到日志(log_errors=1),排查时看 PHP 错误日志;
// - 需要临时调试时,设环境变量 MOVIELOG_DEBUG=1 即可把错误显示打开。
$__movielog_debug = getenv('MOVIELOG_DEBUG') === '1';
error_reporting(E_ALL);
2026-10-31 21:35:41 +08:00
ini_set('display_errors', $__movielog_debug ? '1' : '0');
ini_set('log_errors', '1');
unset($__movielog_debug);
session_start();
// 跨域资源引用策略:本站页面加载对象存储(OSS / COS / 七牛)等第三方域名的图片时,
// 浏览器不发送 Referer,避免被云厂商的防盗链(bucket referer policy)拦成 403。
// 同源请求(本站自身的页面与接口)仍照常携带 Referer,不影响任何安全检查。
if (!headers_sent()) {
header('Referrer-Policy: same-origin');
}
// 项目根目录(lib/ 下的模块统一用它拼接绝对路径)
define('ROOT_DIR', __DIR__);
// 数据库路径
define('DB_PATH', ROOT_DIR . '/db/movies.db');
// 上传目录
define('UPLOAD_DIR', ROOT_DIR . '/uploads/');
define('POSTER_DIR', UPLOAD_DIR . 'posters/');
define('TICKET_DIR', UPLOAD_DIR . 'tickets/');
define('PHOTO_DIR', UPLOAD_DIR . 'photos/');
define('AVATAR_DIR', UPLOAD_DIR . 'avatars/');
// 创建上传目录
foreach ([POSTER_DIR, TICKET_DIR, PHOTO_DIR, AVATAR_DIR] as $dir) {
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
}
2026-10-31 21:35:41 +08:00
// ===== 安装检查(必须在加载任何业务模块、建库之前)=====
//
// 未安装时:把请求引到 install.php,并立刻退出 —— 绝不能继续往下走到 initDB()。
// 判据只看锁文件 db/.installed,由 install.php 装完时写入。
//
// 为什么不能「先 initDB() 再判断」:
// initDB() 会建库建表,并在 admins 为空时插入 admin/123456。
// 那样「打开任意页面」这个动作就等于完成了一半安装,还会把弱口令暴露出去
// (FeedLite 踩过同一个坑:访问动作本身建库 → 「未安装」永远判不出来)。
//
// 例外:install.php 自身、以及 css/js 等静态资源不受此检查约束
// (install.php 不加载本文件;静态资源由 Web 服务器直接返回,不经过 PHP)。
if (!is_file(ROOT_DIR . '/db/.installed')) {
// 当前脚本名(兼容子目录部署)
$self = basename($_SERVER['SCRIPT_NAME'] ?? '');
if ($self !== 'install.php' && PHP_SAPI !== 'cli') {
header('Location: install.php');
exit;
}
}
// ===== 功能模块 =====
require_once ROOT_DIR . '/lib/db.php'; // 数据库连接与初始化
require_once ROOT_DIR . '/lib/settings.php'; // 系统设置读写
require_once ROOT_DIR . '/lib/storage.php'; // 对象存储门面(含各云厂商驱动)
require_once ROOT_DIR . '/lib/helpers.php'; // 通用工具函数
require_once ROOT_DIR . '/lib/theme.php'; // 界面配色主题(注册表 / 当前主题)
require_once ROOT_DIR . '/lib/auth.php'; // 登录校验与账号管理
require_once ROOT_DIR . '/lib/movies.php'; // 电影 / 影院 / 搜索
require_once ROOT_DIR . '/lib/reviews.php'; // 评价与评价下的讨论
require_once ROOT_DIR . '/lib/stats.php'; // 统计与年度报告
// 初始化数据库
2026-10-31 21:35:41 +08:00
// 走到这里说明已装过(上面的检查已拦截未安装的情况),
// 因此 seedDefaultAdmin 传 false:老库本来就有人,空库也不该被塞一个 admin/123456。
initDB(false);