category.php7.4 KB
<?php
// 1. 引入配置文件并连接数据库
if (!file_exists(__DIR__ . '/config.php')) {
die('系统未安装!请先访问 <a href="install/">安装向导</a>');
}
require __DIR__ . '/config.php';
try {
$dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4";
$pdo = new PDO($dsn, DB_USER, DB_PASS, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
} catch (PDOException $e) {
die("数据库连接失败:" . $e->getMessage());
}
// 2. 获取分类 ID 和当前页码
$category_id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
$current_page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
$per_page = 6; // 每页显示 6 条
if ($category_id <= 0) {
http_response_code(404);
die('未指定有效的分类');
}
// 3. 获取分类信息(用于页面标题)
$stmt_cat = $pdo->prepare("SELECT name FROM categories WHERE id = :id LIMIT 1");
$stmt_cat->execute([':id' => $category_id]);
$category = $stmt_cat->fetch(PDO::FETCH_ASSOC);
if (!$category) {
http_response_code(404);
die('该分类不存在');
}
// 4. 获取该分类下的文章总数,用于计算分页
$total_sql = "SELECT COUNT(*) as total FROM posts WHERE category_id = :cat_id";
// 动态检测 status 字段
$has_status = false;
try {
$pdo->query("SELECT status FROM posts LIMIT 1");
$has_status = true;
} catch (PDOException $e) {}
if ($has_status) {
$total_sql .= " AND status = 'published'";
}
$stmt_total = $pdo->prepare($total_sql);
$stmt_total->execute([':cat_id' => $category_id]);
$total_posts = $stmt_total->fetch(PDO::FETCH_ASSOC)['total'];
$total_pages = ceil($total_posts / $per_page);
// 防止请求超出范围的页码
if ($current_page > $total_pages && $total_pages > 0) {
$current_page = $total_pages;
}
// 5. 获取当前页的文章数据
$offset = ($current_page - 1) * $per_page;
$sql = "SELECT
p.id, p.title, p.content, p.created_at,
u.username AS author_name
FROM posts p
LEFT JOIN users u ON p.author_id = u.id
WHERE p.category_id = :cat_id";
if ($has_status) {
$sql .= " AND p.status = 'published'";
}
$sql .= " ORDER BY p.created_at DESC LIMIT :limit OFFSET :offset";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':cat_id', $category_id, PDO::PARAM_INT);
$stmt->bindValue(':limit', $per_page, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$posts = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 【复用】获取所有独立页用于顶部导航
$stmt_pages = $pdo->query("SELECT id, title, slug FROM pages ORDER BY id ASC");
$pages = $stmt_pages->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlspecialchars($category['name']); ?> - 我的 PHP 博客</title>
<style>
nav ul { list-style: none; margin: 0; padding: 0; display: flex; gap: 5px; }
nav ul li a { display: block; padding: 8px 12px; color: #ddd; text-decoration: none; font-size: 14px; border-radius: 4px; transition: 0.3s; }
nav ul li a:hover { background-color: #555; color: #fff; }
.container { max-width: 800px; margin: 30px auto; padding: 0 15px; }
.page-header { margin-bottom: 20px; }
.page-header h2 { font-size: 24px; margin: 0; color: #222; }
.page-header p { font-size: 14px; color: #888; margin: 5px 0 0; }
.post-card { background: #fff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.05); padding: 25px; margin-bottom: 20px; transition: transform 0.2s; }
.post-card:hover { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0,0,0,0.1); }
.post-title { font-size: 20px; margin: 0 0 10px; }
.post-title a { text-decoration: none; color: #333; transition: color 0.2s; }
.post-title a:hover { color: #007bff; }
.post-meta { font-size: 12px; color: #888; margin-bottom: 15px; display: flex; gap: 15px; flex-wrap: wrap; }
.post-excerpt { font-size: 14px; line-height: 1.6; color: #555; }
/* 分页样式 */
.pagination { display: flex; justify-content: center; align-items: center; gap: 10px; margin-top: 30px; padding-bottom: 30px; }
.pagination a, .pagination span { padding: 8px 15px; border-radius: 4px; text-decoration: none; font-size: 14px; transition: 0.3s; }
.pagination a { background: #fff; border: 1px solid #ddd; color: #333; }
.pagination a:hover { background: #007bff; color: #fff; border-color: #007bff; }
.pagination span.current { background: #007bff; color: #fff; border: 1px solid #007bff; cursor: default; }
.pagination span.disabled { background: #f8f9fa; color: #aaa; border: 1px solid #eee; cursor: not-allowed; }
</style>
</head>
<body>
<!-- 搜索弹窗 -->
<?php require_once __DIR__ . '/search-tc.php'; ?>
<div class="container">
<?php require_once __DIR__ . '/header.php'; ?>
<div class="main-content">
<div class="content-left">
<div class="page-header">
<h2>📁 <?php echo htmlspecialchars($category['name']); ?></h2>
<p>共有 <?php echo $total_posts; ?> 篇文章,当前第 <?php echo $current_page; ?>/<?php echo $total_pages ?: 1; ?> 页</p>
</div>
<?php if (!empty($posts)): ?>
<?php foreach ($posts as $post): ?>
<div class="post-card">
<h2 class="post-title"><a href="post.php?id=<?php echo $post['id']; ?>"><?php echo htmlspecialchars($post['title']); ?></a></h2>
<div class="post-meta">
<span>🕒 <?php echo date('Y-m-d H:i', strtotime($post['created_at'])); ?></span>
<?php if (!empty($post['author_name'])): ?>
<span>✍️ <?php echo htmlspecialchars($post['author_name']); ?></span>
<?php endif; ?>
</div>
<div class="post-excerpt">
<?php echo mb_substr(strip_tags($post['content']), 0, 150) . '...'; ?>
</div>
</div>
<?php endforeach; ?>
<!-- 分页控件 -->
<div class="pagination">
<?php if ($current_page > 1): ?>
<a href="?id=<?php echo $category_id; ?>&page=<?php echo $current_page - 1; ?>">« 上一页</a>
<?php else: ?>
<span class="disabled">« 上一页</span>
<?php endif; ?>
<span class="current">第 <?php echo $current_page; ?> 页</span>
<?php if ($current_page < $total_pages): ?>
<a href="?id=<?php echo $category_id; ?>&page=<?php echo $current_page + 1; ?>">下一页 »</a>
<?php else: ?>
<span class="disabled">下一页 »</span>
<?php endif; ?>
</div>
<?php else: ?>
<div class="post-card" style="text-align:center; color:#aaa;">
<p>该分类下暂无已发布的文章。</p>
</div>
<?php endif; ?>
</div>
<?php require_once __DIR__ . '/sidebar-right.php'; ?>
</div>
<!-- 【结构优化】将 footer 移出 container,使其能够横跨整个屏幕宽度 -->
<?php require_once __DIR__ . '/footer.php'; ?>
</div>
</body>
</html>