-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbootstrap.php
More file actions
100 lines (88 loc) · 4.64 KB
/
bootstrap.php
File metadata and controls
100 lines (88 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<?php
declare(strict_types=1);
/**
* LitePic bootstrap.
*
* Single entry point that all PHP requests flow through. Responsibilities:
* 1. Define APP_ROOT
* 2. Register the PSR-4 autoloader
* 3. Bring up Logger
* 4. Load .env (optional — no .env required; DB is the canonical store)
* 5. Open the SQLite connection and run any pending migrations
* (migration 008 seeds all defaults into the settings table)
* 6. Warm the settings cache from the DB (one SELECT * FROM settings),
* then seed from .env on first boot only (one-time, idempotent)
* 7. Pull in `config.php` constants (define()s read from settings cache
* first via env_value/bool/csv, then $_ENV, then defaults)
*/
if (!defined('APP_ROOT')) {
define('APP_ROOT', __DIR__);
}
if (PHP_SAPI !== 'cli' && is_file(APP_ROOT . '/.maintenance')) {
$uriPath = parse_url((string)($_SERVER['REQUEST_URI'] ?? '/'), PHP_URL_PATH);
$path = is_string($uriPath) ? $uriPath : '/';
$isUpdater = str_starts_with($path, '/api/v1/update');
if (!$isUpdater) {
http_response_code(503);
header('Retry-After: 120');
if (str_starts_with($path, '/api/')) {
header('Content-Type: application/json; charset=utf-8');
echo json_encode(['status' => 'error', 'message' => 'LitePic 正在更新,请稍后再试'], JSON_UNESCAPED_UNICODE);
} else {
header('Content-Type: text/html; charset=utf-8');
echo '<!doctype html><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>LitePic 正在更新</title><style>body{margin:0;min-height:100vh;display:grid;place-items:center;background:#0f1116;color:#e6eef8;font-family:-apple-system,BlinkMacSystemFont,"Noto Sans SC",sans-serif}.box{border:1px solid #ffffff14;padding:28px 34px;background:#151a24}h1{margin:0 0 8px;font-size:22px}p{margin:0;color:#9aa0a6}</style><div class="box"><h1>LitePic 正在更新</h1><p>程序文件正在替换,请稍后刷新页面。</p></div>';
}
exit;
}
}
require_once APP_ROOT . '/app/Core/Autoloader.php';
\LitePic\Core\Autoloader::register('LitePic\\', APP_ROOT . '/app');
\LitePic\Core\Logger::init(APP_ROOT . '/logs');
// .env is now optional — load it into $_ENV so first-boot installs and
// CLI scripts that ship a .env still work, but every save via the
// settings UI persists to the DB and shadows the .env value from then on.
\LitePic\Core\Config::init(APP_ROOT . '/.env');
\LitePic\Core\Database::init(APP_ROOT . '/data/litepic.sqlite');
try {
$migrator = new \LitePic\Core\Migration(APP_ROOT . '/app/Migrations');
$migrator->run();
} catch (\Throwable $e) {
\LitePic\Core\Logger::error('Migration failed: ' . $e->getMessage(), [
'trace' => $e->getTraceAsString(),
]);
if (\LitePic\Core\Config::bool('DEBUG', false)) {
throw $e;
}
}
// Warm the settings cache (DB → static map). On a fresh install where
// the settings table is still empty, seedFromEnvIfEmpty() copies any
// values present in .env into the DB so subsequent UI saves don't get
// silently shadowed. After this point env_value/bool/csv read DB-first.
\LitePic\Core\Config::warmSettings();
\LitePic\Core\Config::seedFromEnvIfEmpty();
// Constants (SITE_NAME, MAX_FILE_SIZE, WATERMARK_*, S3_*, ENABLE_*).
// Views and templates reference these directly. The env_value/bool/csv
// helpers consult the settings cache first, so define() effectively
// loads from SQLite without any caller changes.
require_once APP_ROOT . '/config.php';
// Idle-site safety net for the worker queue. Arms a shutdown hook on
// every web request that fires a drain at most once per 24h (default)
// when no real cron is configured. No-op on CLI.
\LitePic\Service\Queue\HeartbeatScheduler::arm();
// Liveness sample for the runtime-info uptime strip. Every PHP request
// records one ping per minute (PRIMARY KEY in liveness_pings collapses
// concurrent inserts). Skip on CLI so background workers don't flood it.
if (PHP_SAPI !== 'cli') {
\LitePic\Service\Stats\LivenessTracker::recordOnce();
} else {
// CLI fast-path: snapshot all the server-side stats that restricted
// PHP-FPM can't read (BT panel locks /proc + shell_exec from HTTP, but
// CLI has full access). Cached to settings; HTTP requests fall back
// to the snapshot when their own probes fail.
// - CPU cores: cached once forever (hardware constant)
// - Memory total/used + uptime + load: refreshed every CLI run
try {
\LitePic\Service\Stats\ServerInfo::probeAndCacheCpuCoresIfMissing();
\LitePic\Service\Stats\ServerInfo::probeAndCacheServerStats();
} catch (\Throwable $_) { /* best-effort */ }
}