perf: V0.9.4 商品列表分页 + sitemap 文件缓存 + banner/asset/gzip/类型修复

- P1: Product::listing() 分页(WHERE status=1+LIMIT/OFFSET+总数),ProductController 改用并加翻页器,消除列表全表
- P1: outputSitemap() 加 storage/cache/sitemap.xml 文件缓存(TTL 3600s),消除每次爬虫全表
- P2: 首页 banner 改 whereLimit('status',1,20)
- P2: asset() 追加 ?v=filemtime 版本串,theme.css 改后自动击穿 1y 浏览器缓存
- P2: nginx 启用 gzip(文本资源压缩)
- P2: Model::count() $val 隐式可空改 mixed(PHP 8.4+ 弃用)
This commit is contained in:
2026-08-08 23:53:52 +08:00
parent 2285998618
commit d5c1edefae
8 changed files with 83 additions and 7 deletions
+15 -1
View File
@@ -328,9 +328,17 @@ class App
return $v;
}
/** 动态生成 Sitemap XMLGoogle/Bing/Baidu 自动抓取) */
/** 动态生成 Sitemap XMLGoogle/Bing/Baidu 自动抓取)。V0.9.4:加文件缓存(TTL),避免每次爬虫请求全表扫描。 */
private static function outputSitemap(): void
{
$cacheFile = rtrim(BASE_PATH, '/') . '/storage/cache/sitemap.xml';
$ttl = 3600;
if (is_file($cacheFile) && (time() - filemtime($cacheFile)) < $ttl) {
header('Content-Type: application/xml; charset=utf-8');
readfile($cacheFile);
exit;
}
ob_start();
header('Content-Type: application/xml; charset=utf-8');
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
@@ -402,6 +410,12 @@ class App
}
echo '</urlset>';
$xml = ob_get_clean();
// 写文件缓存(best-effort:目录不存在则创建,写失败不影响本次输出)
$dir = dirname($cacheFile);
if (!is_dir($dir)) @mkdir($dir, 0755, true);
if (is_dir($dir)) @file_put_contents($cacheFile, $xml);
echo $xml;
exit;
}
}
+8 -1
View File
@@ -24,7 +24,14 @@ if (!function_exists('site_url')) {
}
function asset(string $path = ''): string
{
return site_url('assets/' . ltrim($path, '/'));
$url = site_url('assets/' . ltrim($path, '/'));
// V0.9.4:追加文件 mtime 作为版本串,使 theme.css 等静态资源在「重新生成/部署」后自动击穿浏览器长缓存
//nginx 对已改资源设了 expires 1y,无版本串会导致老访客最长 1 年看不到更新)。
$real = rtrim(BASE_PATH, '/') . '/public/assets/' . ltrim($path, '/');
if (is_file($real)) {
$url .= '?v=' . filemtime($real);
}
return $url;
}
function e($v): string
{
+1 -1
View File
@@ -193,7 +193,7 @@ class Model
* @param string|null $col 过滤列(null 表示全表计数)
* @param mixed $val 过滤值
*/
public function count(?string $col = null, $val = null): int
public function count(?string $col = null, mixed $val = null): int
{
if (Db::driver() === 'mysql') {
if ($col === null) {