require_once '../functions.php';
get_userinfo();
$posts = mysql_all('select * from posts;');
<tbody>
<?php foreach ($posts as $item): ?>
<tr>
<td class="text-center"><input type="checkbox"></td>
<td><?php echo $item['title']; ?></td>
<td><?php echo $item['user_id']?></td>
<td><?php echo $item['category_id']?></td>
<td class="text-center"><?php echo $item['created']?></td>
<td class="text-center"><?php echo $item['status']?></td>
<td class="text-center">
<a href="javascript:;" class="btn btn-default btn-xs">编辑</a>
<a href="javascript:;" class="btn btn-danger btn-xs">删除</a>
</td>
</tr>
<?php endforeach?>
</tbody>
1.用函数去格式化时间
// 用函数去处理时间
function convert_date ($created) {
// 数据库中存储的时间 '2017-07-01 08:08:00'
//格式化成 => '2017年07月01日 08:08:00
// 如果配置文件没有配置时区
// date_default_timezone_set('PRC');
$timestamp = strtotime($created);
return date('Y年m月d日H:i:s', $timestamp);
}
<td class="text-center"><?php echo convert_date($item['created']); ?></td>
// 用函数去处理状态
function convert_status($status){
$dict = array(
'published' => '已发布',
'drafted' => '草稿',
'trashed' => '回收站'
);
return isset($dict[$status]) ? $dict[$status] : '未知';
}
<td class="text-center"><?php echo convert_status($item['status']); ?></td>
//php部分
//用函数去处理作者和分类方法一
function get_user($user_id){
return mysql_one ("select nickname from users where id = {$user_id}['nickname']");
}
function get_category($category_id){
return mysql_one ("select name from categories where id = {$category_id}['name']");
}
//Html部分
//用函数去处理作者和状态
<td><?php echo get_user($item['user_id']); ?></td>
<td><?php echo get_category($item['category_id']); ?></td>
//php部分
$posts = mysql_all('select
posts.id,
posts.title,
posts.created,
posts.status,
users.nickname as user_name,
categories.name as category_name
from posts
inner join categories on posts.category_id = categories.id
inner join users on posts.user_id = users.id');
2.2 更改html部分
//html部分
<td><?php echo $item['user_name']; ?></td>
<td><?php echo $item['category_name']; ?></td>
想要是实现分页的话,posts表中的数据显然不够做这个功能,所以需要导入更多的测试数据
limit 子句中的 0 和 10 不是一成不变的,应该跟着页码的变化而变化,具体的规则就是:
第 1 页 limit 0, 10
第 2 页 limit 10, 10
第 3 页 limit 20, 10
第 4 页 limit 30, 10 …
根据以上规则得出公式: offset = (page - 1) * size
// 处理分页参数
$size = 5;
// // 计算越过多少条
$offset = ($page - 1) * $size;
// 用关联数据中方式去查询数据库
// 获取全部数据
$posts = mysql_all("select
posts.id,
posts.title,
users.nickname as user_name,
categories.name as category_name,
posts.created,
posts.status
from posts
inner join categories on posts.category_id = categories.id
inner join users on posts.user_id = users.id
order by posts.created desc
limit {
$offset}, {
$size};
");
一般分页都是通过 URL 传递一个页码参数
也就是说,我们应该在页面开始执行的时候获取这个 URL 参数
获取分页参数 没有或传过来的不是数字的话默认为 1 $page = isset($_GET['p']) && is_numeric($_GET['p'
$page = empty($_GET['page']) ? 1 : (int)$_GET['page'];
//Php部分
// 计算页码
$visiables = 5;
$region = ($visiables -1) / 2;
$begin = $page - $region;
$end = $page + $region;
//Html部分
<ul class="pagination pagination-sm pull-right">
<li><a href="#">上一页</a></li>
<?php for ($i = $begin; $i <= $end; $i++): ?>
<li<?php echo $i === $page ? ' class="active"' : '' ?>><a href="?page="><?php echo $i; ?></a></li>
<?php endfor ?>
<li><a href="#">下一页</a></li>
</ul>
// 计算页码开始
$visiables = 5;
$region = ($visiables - 1) / 2; // 左右区间
$begin = $page - $region; // 开始页码
// $end = $page + $region;
$end = $begin + $visiables; // 结束页码 + 1
//出现$begin不合理的情况处理
//$begin必须大于1
if ($begin < 1) {
$begin = 1;
// begin 修改意味着必须要改 end
$end = $begin + $visiables;
}
//$end不得超过最大page
//求出最大页码
$total_count = (int)mysql_one('select count(1) as num from posts;')['num'];
$total_pages = (int)ceil($total_count / $size);
// 判断
if ($end > $total_pages + 1) {
// end 超出范围
$end = $total_pages + 1;
// end 修改意味着必须要改 begin
$begin = $end - $visiables;
if ($begin < 1) {
$begin = 1;
}
}
//html部分,与上面不同的是
//将for ($i = $begin; $i <= $end; $i++)更改成 for ($i = $begin; $i < $end; $i++)
<li>
<a href="#">上一页</a></li>
<?php for ($i = $begin; $i < $end; $i++): ?>
<li<?php echo $i === $page ? ' class="active"' : ''; ?>><a href="?page="><?php echo $i; ?></a></li>
<?php endfor ?>
<li><a href="#">下一页</a>
</li>
$total_pages = ceil($total_count / $size);
修改后的代码
$total_pages = (int)ceil($total_count / $size);
解决办法二:将三个 === 更改成 两个 == (让它变得没有那么严谨)
<li<?php echo $i == $page ? ' class="active"' : ''; ?>><a href="?page="><?php echo $i; ?></a></li>
//$end不得超过最大page
//求出最大页码
$total_count = (int)mysql_one('select count(1) as num from posts;')['num'];
$total_pages = (int)ceil($total_count / $size);
更改成:
//$end不得超过最大page
//求出最大页码
$total_count = (int)mysql_one('select count(1) as num
from posts
inner join categories on posts.category_id = categories.id
inner join users on posts.user_id = users.id;')['num'];
$total_pages = (int)ceil($total_count / $size);
// 分类筛选
if(!empty($_GET['category'])){
$where .= ' and posts.category_id = ' . $_GET['category'];
}
//防止category=all时报错,所以更改成
if (isset($_GET['category']) && $_GET['category'] !== 'all') {
$where .= ' and posts.category_id = ' . $_GET['category'];
}
//HTML部分 利用foreach遍历循环得到的categories表中的数据并呈现在页面上
//给form表单设置action,表单自动默认method = "get",此处应该使用get方式
//所以可以不用设置method
<form class="form-inline" action="">
//给select加上name属性
<select name="category" class="form-control input-sm">
//给所有分类添加一个value="all",用来默认显示所有分类
<option value="all">所有分类</option>
//将未分类删掉,遍历循环categories表中数据
//
<?php foreach ($categories as $item): ?>
//给分类的option添加value = "id" ,用来作为筛选的标识
//再加上一个判断当前是否存在$_GET['category'],用来判断当前所选项,记住筛选状态,并展示在框内
<option value=""<?php echo isset($_GET['category']) && $_GET['category'] == $item['id'] ? ' selected' : '' ?>>
<?php echo $item['name']; ?>
</option>
<?php endforeach ?>
</select>
//PHP部分
//筛选状态
if (isset($_GET['status']) && $_GET['status'] !== 'all') {
$where .= " and posts.status = '{$_GET['status']}'";
}
//HTML部分
//给每一个option标签都加上对应的value属性
//并且判断是否存在$_GET['status'],用来判断当前所选项,记住筛选状态,并展示在框内
<select name="status" class="form-control input-sm">
<option value="all">所有状态</option>
<option value="drafted"<?php echo isset($_GET['status']) && $_GET['status'] == 'drafted' ? ' selected' : '' ?>>草稿</option>
<option value="published"<?php echo isset($_GET['status']) && $_GET['status'] == 'published' ? ' selected' : '' ?>>已发布</option>
<option value="trashed"<?php echo isset($_GET['status']) && $_GET['status'] == 'trashed' ? ' selected' : '' ?>>回收站</option>
</select>
当我们加上 where 语句时,可实现数据的筛选,where语句筛选数据都是根据数据的唯一标识(也就是id)来进行筛选
//sql语句的注入
// 数据库查询筛选条件(默认为 1 = 1,相当于没有条件)
$where = '1 = 1';
$posts = mysql_all("select
posts.id,
posts.title,
users.nickname as user_name,
categories.name as category_name,
posts.created,
posts.status
from posts
inner join categories on posts.category_id = categories.id
inner join users on posts.user_id = users.id
where {
$where}
order by posts.created desc
limit {
$offset}, {
$size};
");
$total_count = (int)mysql_one("select count(1) as num from posts
inner join categories on posts.category_id = categories.id
inner join users on posts.user_id = users.id
where {
$where};")['num'];
$total_pages = (int)ceil($total_count / $size);
///Php部分
//定义一个serch
$search = '';
//在每个筛选下加上serch
// 分类筛选
// if(!empty($_GET['category'])){
if (isset($_GET['category']) && $_GET['category'] !== 'all') {
$where .= ' and posts.category_id = ' . $_GET['category'];
$search .= '&category=' . $_GET['category'];
}
//筛选状态
if (isset($_GET['status']) && $_GET['status'] !== 'all') {
$where .= " and posts.status = '{$_GET['status']}'";
$search .= '&status=' . $_GET['status'];
}
//Html部分
//没有处理分类和状态显示所有分类和状态之前
<li><a href="#">上一页</a></li>
<?php for ($i = $begin; $i < $end; $i++): ?>
<li<?php echo $i === $page ? ' class="active"' : ''; ?>><a href="?page=">
<?php echo $i; ?></a></li>
<?php endfor ?>
<li><a href="#">下一页</a></li>-->
//处理分类和状态显示所有分类和状态之后
<li><a href="#">上一页</a></li>
<?php for ($i = $begin; $i < $end; $i++): ?>
<li<?php echo $i == $page ? ' class="active"' : '' ?>><a href="?page="><?php echo $i; ?></a></li>
<?php endfor ?>
<li><a href="#">下一页</a></li>
if ($page > $total_pages) {
// 跳转到第最后页
header('Location: /admin/posts.php?page=' . $total_pages . $search);
}
//Html部分
<a href="/admin/post-delete.php?id=" class="btn btn-danger btn-xs">删除</a>
新增一个 post-delete.php 文件与 category-delete.php 类似
post-delete.php
<?php
/**
* 根据客户端传递过来的ID删除对应数据
*/
require_once '../functions.php';
if (empty($_GET['id'])) {
exit('缺少必要参数');
}
// $id = (int)$_GET['id'];
$id = $_GET['id'];
$rows = mysql_change('delete from posts where id in (' . $id . ');');
header('Location: ' . $_SERVER['HTTP_REFERER']);
// http 中的 referer 用来标识当前请求的来源
//末尾这句话的作用是为了当用户删除最后一页数据时,不会报错,返回的是倒数第二页,显示正确
posts.php完整代码
<?php
header("Content-Type: text/html;charset=utf-8");
require_once '../functions.php';
get_userinfo();
// 处理分页参数
$page = empty($_GET['page']) ? 1 : (int)$_GET['page'];
$size = 20;
// 计算出越过多少条
$offset = ($page - 1) * $size;
// 接收筛选数据
$where = '1 = 1';
$search = '';
// 分类筛选
if (isset($_GET['category']) && $_GET['category'] !== 'all') {
$where .= ' and posts.category_id = ' . $_GET['category'];
$search .= '&category=' . $_GET['category'];
}
//筛选状态
if (isset($_GET['status']) && $_GET['status'] !== 'all') {
$where .= " and posts.status = '{$_GET['status']}'";
$search .= '&status=' . $_GET['status'];
}
// 用关联数据中方式去查询数据库
// 获取全部数据
$posts = mysql_all("select
posts.id,
posts.title,
users.nickname as user_name,
categories.name as category_name,
posts.created,
posts.status
from posts
inner join categories on posts.category_id = categories.id
inner join users on posts.user_id = users.id
where {
$where}
order by posts.created desc
limit {
$offset}, {
$size};
");
// 处理分页页码===============================
// 计算页码
// 计算页码开始
$visiables = 5;
$region = ($visiables - 1) / 2; // 左右区间
$begin = $page - $region; // 开始页码
$end = $begin + $visiables; // 结束页码 + 1
//出现$begin不合理的情况处理
//$begin必须大于1
if ($begin < 1) {
$begin = 1;
// begin 修改意味着必须要改 end
$end = $begin + $visiables;
}
//$end不得超过最大page
//求出最大页码
$total_count = (int)mysql_one("select count(1) as num from posts
inner join categories on posts.category_id = categories.id
inner join users on posts.user_id = users.id
where {
$where};")['num'];
$total_pages = (int)ceil($total_count / $size);
// 判断
if ($end > $total_pages + 1) {
// end 超出范围
$end = $total_pages + 1;
// end 修改意味着必须要改 begin
$begin = $end - $visiables;
if ($begin < 1) {
$begin = 1;
}
}
if ($page > $total_pages) {
// 跳转到第最后页
header('Location: /admin/posts.php?page=' . $total_pages . $search);
}
// 用函数去处理状态
function convert_status($status){
$dict = array(
'published' => '已发布',
'drafted' => '草稿',
'trashed' => '回收站'
);
return isset($dict[$status]) ? $dict[$status] : '未知';
}
// 用函数去处理时间,格式化时间
function convert_date ($created) {
// 如果配置文件没有配置时区
// date_default_timezone_set('PRC');
$timestamp = strtotime($created);
return date('Y年m月d日H:i:s', $timestamp);
}
$categories = mysql_all('select * from categories;');
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>Posts « Admin</title>
<link rel="stylesheet" href="/static/assets/vendors/bootstrap/css/bootstrap.css">
<link rel="stylesheet" href="/static/assets/vendors/font-awesome/css/font-awesome.css">
<link rel="stylesheet" href="/static/assets/vendors/nprogress/nprogress.css">
<link rel="stylesheet" href="/static/assets/css/admin.css">
<script src="/static/assets/vendors/nprogress/nprogress.js"></script>
</head>
<body>
<script>NProgress.start()</script>
<div class="main">
<?php include 'com/nav.php';?>
<div class="container-fluid">
<div class="page-title">
<h1>所有文章</h1>
<a href="post-add.php" class="btn btn-primary btn-xs">写文章</a>
</div>
<div class="page-action">
<!-- show when multiple checked -->
<a class="btn btn-danger btn-sm" href="javascript:;" style="display: none">批量删除</a>
<form class="form-inline" action="" >
<select name="category" class="form-control input-sm">
<option value="all">所有分类</option>
<!-- <option value="">未分类</option> -->
<?php foreach ($categories as $item): ?>
<option value=""<?php echo isset($_GET['category']) && $_GET['category'] == $item['id'] ? ' selected' : '' ?>>
<?php echo $item['name']; ?>
</option>
<?php endforeach ?>
</select>
<select name="status" class="form-control input-sm">
<option value="all">所有状态</option>
<option value="drafted"<?php echo isset($_GET['status']) && $_GET['status'] == 'drafted' ? ' selected' : '' ?>>草稿</option>
<option value="published"<?php echo isset($_GET['status']) && $_GET['status'] == 'published' ? ' selected' : '' ?>>已发布</option>
<option value="trashed"<?php echo isset($_GET['status']) && $_GET['status'] == 'trashed' ? ' selected' : '' ?>>回收站</option>
</select>
<button class="btn btn-default btn-sm">筛选</button>
</form>
<ul class="pagination pagination-sm pull-right">
<li><a href="#">上一页</a></li>
<?php for ($i = $begin; $i < $end; $i++): ?>
<li<?php echo $i == $page ? ' class="active"' : '' ?>><a href="?page="><?php echo $i; ?></a></li>
<?php endfor ?>
<li><a href="#">下一页</a></li>
</ul>
</div>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th class="text-center" width="40"><input type="checkbox"></th>
<th>标题</th>
<th>作者</th>
<th>分类</th>
<th class="text-center">发表时间</th>
<th class="text-center">状态</th>
<th class="text-center" width="100">操作</th>
</tr>
</thead>
<tbody>
<?php foreach ($posts as $item): ?>
<tr>
<td class="text-center"><input type="checkbox"></td>
<td><?php echo $item['title']; ?></td>
//用关联数据库的方式去处理作者和状态
<td><?php echo $item['user_name']; ?></td>
<td><?php echo $item['category_name']; ?></td>
//用函数去处理时间
<td class="text-center"><?php echo convert_date($item['created']); ?></td>
// 用函数处理后显示状态
<td class="text-center"><?php echo convert_status($item['status']); ?></td>
<td class="text-center">
<a href="javascript:;" class="btn btn-default btn-xs">编辑</a>
<!-- <a href="javascript:;" class="btn btn-danger btn-xs">删除</a> -->
<a href="/admin/post-delete.php?id=" class="btn btn-danger btn-xs">删除</a>
</td>
</tr>
<?php endforeach?>
</tbody>
</table>
</div>
</div>
<?php $current_page='posts';?>
<?php include 'com/sidebar.php';?>
<script src="/static/assets/vendors/jquery/jquery.js"></script>
<script src="/static/assets/vendors/bootstrap/js/bootstrap.js"></script>
<script>NProgress.done()</script>
</body>
</html>