PHP寥寥几行代码轻松实现百度搜索那样的分页列表和导航链接,某些语言的拥趸哭晕在厕所.
<?php
$app = array(
'db_prefix' => 'phpbest_',
'db_sqlite' => '/dev/shm/phpbest/phpbest.db3',
);
//数据库连接单例
function db() {
global $app;
static $db;
if($db) {
return $db;
} else {
try {
$db = new PDO('sqlite:'.$app['db_sqlite']);
} catch(PDOException $e) {
echo $e->getMessage();
exit();
}
return $db;
}
}
//分页导航链接
function page_nav($page, $page_size = 10, $before = 5, $after = 4) {
$page = intval($page);
$page_size = intval($page_size);
global $app;
$db = db();
$table = $app['db_prefix'].'post';
$arr = $db->query("SELECT count(id) FROM $table")->fetchAll(PDO::FETCH_NUM);
$records = $arr[0][0]; //记录数
$pages = ceil($records/$page_size); //页数
if($pages == 0) return;
if($page <= 0 || $page > $pages) return;
$html = '<p>当前页:前输出5页,后输出4页</p>';
$html .= '<a href="?page=1">最前</a>';
if($page != 1) { $html .= '<a href="?page='.($page - 1).'">上一页</a>'; }
if($page <= $before) { for($i = 1; $i < $page; $i++) { $html .= '<a href="?page='.$i.'">第'.$i.'页</a>'; } }
else { for($i = $page - $before; $i < $page; $i++) { $html .= '<a href="?page='.$i.'">第'.$i.'页</a>'; } }
$html .= '<a href="?page='.$page.'">第'.$page.'页(当前页)</a>';
if($pages >= $page + $after) { for($i = $page + 1; $i <= $page + $after; $i++) { $html .= '<a href="?page='.$i.'">第'.$i.'页</a>'; } }
else { for($i = $page + 1; $i <= $pages; $i++) { $html .= '<a href="?page='.$i.'">第'.$i.'页</a>'; } }
if($page != $pages) { $html .= '<a href="?page='.($page + 1).'">下一页</a>'; }
$html .= '<a href="?page='.$pages.'">最后</a>';
return $html;
}
//分页列表内容
function page_list($page, $page_size = 10) {
$page = intval($page);
$page_size = intval($page_size);
global $app;
$db = db();
$table = $app['db_prefix'].'post';
$offset = ($page - 1) * $page_size;
return $db->query("SELECT * FROM $table ORDER BY id DESC LIMIT $page_size OFFSET $offset")->fetchAll(PDO::FETCH_ASSOC);
}
?>
<div class="content pjax">
<?php echo page_nav($_GET['page'], 2); ?>
<ul>
<?php
foreach(page_list($_GET['page'], 2) as $v) {
echo '<li>'.$v['id'].'</li>';
echo '<li>'.$v['title'].'</li>';
echo '<li>'.$v['content'].'</li>';
echo '<li>'.date('Y-m-d H:i:s', strtotime($v['date'])).'</li><br>';
}
?>
</ul>
</div>
<script type="text/javascript" src="jquery.pjax.js"></script>
<script>
(function($){
$(function(){
//调用插件,用户点击链接后局部刷新class为pjax(要求唯一)的块并写入历史记录
$(document).pjax("a:not([target='_blank'])", ".pjax");
});
})(jQuery);
</script>
jquery.pjax.js是我写的一个插件,代码简单到差不多每个人都看得懂:
/* jquery.pjax.js */
(function($){
$.fn.pjax = function(selector, container) {
//IE8之流不支持HTML5 onpopstate,自然不会执行插件
if("onpopstate" in window) {
//AJAX加载函数
var load = function(href) {
var time = 600;
$(document).trigger("pjax:start", [time]); //执行开发者的自定义事件(如:显示加载进度条)
var start = new Date().getTime();
$.ajax({
type: "GET",
url: href,
data: {_pjax_: new Date().getTime()}
}).done(function(data){
//在回调函数中解析出head中的title和body中的指定块并更新(这样服务器端就不需要改变输出格式)
var dom = $("<div>").html(data);
document.title = dom.find("title").first().text();
$(container).first().html(dom.find(container).first().html());
var spend = new Date().getTime() - start;
setTimeout(function(){
$(document).trigger("pjax:done"); //执行开发者的自定义事件(如:隐藏加载进度条)
}, spend >= time ? 0 : time - spend);
});
};
history.replaceState({href:location.href}, "", location.href);
window.onpopstate = function() {
//用户点击后退和前进按钮时触发该事件
if(history.state != null) {
load(history.state.href);
}
}
$(container).on("click", selector, function(e){
//用户点击页面链接时改变地址栏(URL)并写入历史记录以及AJAX加载页面
e.preventDefault();
var href = $(this).attr("href");
if(href != "javascript:void(0)") {
history.pushState({href:href}, "", href);
load(href);
}
});
}
};
})(jQuery);
不支持PJAX的浏览器如IE8会自动退化成原始的链接打开的方式,所以采用PJAX的站点也是可以兼容IE8的.