= htmlspecialchars($article['title']) ?>
= mb_substr(strip_tags($article['description']), 0, 100) ?>...
在实际的Web开发中,我们经常遇到需要按时间维度(如月份)组织数据的场景。比如:
- 新闻网站的月度归档
- 博客系统的文章分类
- 电商平台的销售报表
这类需求的核心在于正确处理数据库中的时间字段,并通过PHP逻辑实现动态分组展示。
sql
CREATE TABLE articles (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
keywords VARCHAR(255),
description TEXT,
content LONGTEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
created_at
:记录创建时间,建议使用TIMESTAMP类型updated_at
字段用于记录修改时间sql
SELECT
id, title,
DATE_FORMAT(created_at, '%Y-%m') AS month_group
FROM articles
ORDER BY created_at DESC;
sql
SELECT
DATE_FORMAT(created_at, '%Y-%m') AS month,
COUNT(*) AS article_count,
GROUP_CONCAT(title SEPARATOR '|||') AS titles
FROM articles
GROUP BY month
ORDER BY month DESC;
php
<?php
// 数据库连接
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'password');
// 执行查询
$stmt = $pdo->query("
SELECT id, title, description,
DATEFORMAT(createdat, '%Y-%m') AS month
FROM articles
ORDER BY created_at DESC
");
// 按月份分组
$articlesByMonth = [];
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$articlesByMonth[$row['month']][] = $row;
}
// 显示逻辑
foreach ($articlesByMonth as $month => $articles) {
echo "
php
<?php
function getMonthlyArticles(PDO $pdo) {
$cacheFile = DIR . '/cache/monthly_articles.cache';
// 检查缓存(1小时有效期)
if (file_exists($cacheFile) &&
time() - filemtime($cacheFile) < 3600) {
return unserialize(file_get_contents($cacheFile));
}
$stmt = $pdo->query("/* 前文的SQL查询 */");
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 处理分组逻辑
$grouped = [];
foreach ($result as $row) {
$grouped[$row['month']][] = $row;
}
// 写入缓存
file_put_contents($cacheFile, serialize($grouped));
return $grouped;
}
?>
html
= mb_substr(strip_tags($article['description']), 0, 100) ?>...
css
.monthly-archive details {
margin-bottom: 15px;
border: 1px solid #eee;
padding: 10px;
border-radius: 5px;
}
.monthly-archive summary {
cursor: pointer;
font-weight: bold;
padding: 5px;
}
.article-list article {
margin-top: 10px;
padding: 8px;
border-left: 3px solid #3498db;
}
数据库索引优化:
sql
CREATE INDEX idx_created_at ON articles(created_at);
分页加载:php
// 获取分页参数
$page = $_GET['page'] ?? 1;
$perPage = 10;
$offset = ($page - 1) * $perPage;
// 修改SQL
$sql = "SELECT ... ORDER BY created_at DESC LIMIT $offset, $perPage";
异步加载:
javascript
fetch('/api/articles?month=2023-01')
.then(response => response.json())
.then(data => renderArticles(data));
多层级时间归档:
关联其他数据:
sql
SELECT a.*, c.name AS category_name
FROM articles a
LEFT JOIN categories c ON a.category_id = c.id
ORDER BY a.created_at DESC
动态时间筛选:php
$startDate = $GET['start'] ?? null;
$endDate = $GET['end'] ?? null;
if ($startDate && $endDate) {
$sql .= " WHERE created_at BETWEEN ? AND ?";
$params = [$startDate, $endDate];
}