CODESHIF - 2021年11月 https://www.codeshif.com/2021/11/ 最有灵魂的开发者 Typecho显示文章阅读次数统计 https://www.codeshif.com/archives/61.html 2021-11-24T16:42:41+08:00 控制台 / 外观 / 编辑当前外观 / 在 functions.php 最后面加入以下代码代码已中加入了cookie验证,让文章浏览次数更具有真实性function get_post_view($archive) { $cid = $archive->cid; $db = Typecho_Db::get(); $prefix = $db->getPrefix(); if (!array_key_exists('views', $db->fetchRow($db->select()->from('table.contents')))) { $db->query('ALTER TABLE `' . $prefix . 'contents` ADD `views` INT(10) DEFAULT 0;'); echo 0; return; } $row = $db->fetchRow($db->select('views')->from('table.contents')->where('cid = ?', $cid)); if ($archive->is('single')) { $views = Typecho_Cookie::get('extend_contents_views'); if(empty($views)){ $views = array(); }else{ $views = explode(',', $views); } if(!in_array($cid,$views)){ $db->query($db->update('table.contents')->rows(array('views' => (int) $row['views'] + 1))->where('cid = ?', $cid)); array_push($views, $cid); $views = implode(',', $views); Typecho_Cookie::set('extend_contents_views', $views); //记录查看cookie } } echo $row['views']; }在需要显示次数的地方 (如 index.php,post.php) 加入下边的代码阅读 <?php get_post_view($this) ?> ThinkPHP数组分页功能详解 https://www.codeshif.com/archives/45.html 2021-11-24T14:50:20+08:00 ThinkPHP数组分页功能详解[TOC]原理首先找到随便一段PHP查询代码带有paginate的,例如$data_list = UserModel::where($map)->order('sort,role,id desc')->paginate();Ctrl+LeftClick点进去看看:Model.php会发现进入到了Model.php文件:见名思意,该文件是MVC框架的Model实现,不过注意这里: * @method Paginator|$this paginate() static 分页拉到顶部可以看到如下:/** * Class Model * @package think * @mixin Query * @method $this scope(string|array $scope) static 查询范围 * @method $this where(mixed $field, string $op = null, mixed $condition = null) static 查询条件 * @method $this whereRaw(string $where, array $bind = [], string $logic = 'AND') static 表达式查询 * @method $this whereExp(string $field, string $condition, array $bind = [], string $logic = 'AND') static 字段表达式查询 * @method $this when(mixed $condition, mixed $query, mixed $otherwise = null) static 条件查询 * @method $this join(mixed $join, mixed $condition = null, string $type = 'INNER', array $bind = []) static JOIN查询 * @method $this view(mixed $join, mixed $field = null, mixed $on = null, string $type = 'INNER') static 视图查询 * @method $this with(mixed $with, callable $callback = null) static 关联预载入 * @method $this count(string $field = '*') static Count统计查询 * @method $this min(string $field, bool $force = true) static Min统计查询 * @method $this max(string $field, bool $force = true) static Max统计查询 * @method $this sum(string $field) static SUM统计查询 * @method $this avg(string $field) static Avg统计查询 * @method $this field(mixed $field, boolean $except = false, string $tableName = '', string $prefix = '', string $alias = '') static 指定查询字段 * @method $this fieldRaw(string $field) static 指定查询字段 * @method $this union(mixed $union, boolean $all = false) static UNION查询 * @method $this limit(mixed $offset, integer $length = null) static 查询LIMIT * @method $this order(mixed $field, string $order = null) static 查询ORDER * @method $this orderRaw(string $field, array $bind = []) static 查询ORDER * @method $this cache(mixed $key = null , integer|\DateTime $expire = null, string $tag = null) static 设置查询缓存 * @method mixed value(string $field, mixed $default = null) static 获取某个字段的值 * @method array column(string $field, string $key = '') static 获取某个列的值 * @method $this find(mixed $data = null) static 查询单个记录 * @method $this findOrFail(mixed $data = null) 查询单个记录 * @method Collection|$this[] select(mixed $data = null) static 查询多个记录 * @method $this get(mixed $data = null,mixed $with = [],bool $cache = false, bool $failException = false) static 查询单个记录 支持关联预载入 * @method $this getOrFail(mixed $data = null,mixed $with = [],bool $cache = false) static 查询单个记录 不存在则抛出异常 * @method $this findOrEmpty(mixed $data = null) static 查询单个记录 不存在则返回空模型 * @method Collection|$this[] all(mixed $data = null,mixed $with = [],bool $cache = false) static 查询多个记录 支持关联预载入 * @method $this withAttr(array $name,\Closure $closure = null) static 动态定义获取器 * @method $this withJoin(string|array $with, string $joinType = '') static * @method $this withCount(string|array $relation, bool $subQuery = true) static 关联统计 * @method $this withSum(string|array $relation, string $field, bool $subQuery = true) static 关联SUM统计 * @method $this withMax(string|array $relation, string $field, bool $subQuery = true) static 关联MAX统计 * @method $this withMin(string|array $relation, string $field, bool $subQuery = true) static 关联Min统计 * @method $this withAvg(string|array $relation, string $field, bool $subQuery = true) static 关联Avg统计 * @method Paginator|$this paginate() static 分页 */也就是说啊,这个Model.php的方法是从Query.php这里搞过来的,那我们来看一下Query.php里面是什么Query.phpQuery.php文件主要是针对数据库链式操作的类,不过其中含有这么一个方法:/** * 分页查询 * @access public * @param int|array $listRows 每页数量 数组表示配置参数 * @param int|bool $simple 是否简洁模式或者总记录数 * @param array $config 配置参数 * page:当前页, * path:url路径, * query:url额外参数, * fragment:url锚点, * var_page:分页变量, * list_rows:每页数量 * type:分页类名 * @return $this[]|\think\Paginator * @throws DbException */ public function paginate($listRows = null, $simple = false, $config = [])那么这也就是说,我们之前的代码:$data_list = UserModel::where($map)->order('sort,role,id desc')->paginate();其方法->paginate();是调用的Query.php中的paginate方法。DIY实现分页解释如果我们想自己查询数据库,例如使用->select();方法:$data_list = UserModel::where($map)->order('sort,role,id desc')->select();没错,得到的$data_list是数组类型,数组类型并不返回Model本身的实例,则无法继续像这样调用paginate方法了:$data_list = UserModel::where($map)->order('sort,role,id desc')->select(); $data_list->paginate(); // 这里是错误的,因为数组没有paginate方法可调用怎么办?虽然无法调用了,但是我们可以自己创造实例去呀?但是我们需要先了解paginate方法的类在哪对吧?Paginator.php根据查询,弄到了paginate的方法原类对象是Paginator,所在位置thinkphp/library/think/Paginator.php:它是一个abstract抽象类,抽象类是不能实例化的。abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable不过我们可以提前看看它所提供的方法:public function __construct($items, $listRows, $currentPage = null, $total = null, $simple = false, $options = []) public static function make($items, $listRows, $currentPage = null, $total = null, $simple = false, $options = [])这两个方法,一个是用于构造对象用的构造函数__construct,另外一个是静态方法make,看参数应该知道,这就是我们想要找的类。Bootstrap.php再来看看Bootstrap,这个类继承自Paginator抽象类,也就是Paginator抽象类的实现类,class Bootstrap extends Paginator所在位置:thinkphp/library/think/paginator/driver/Bootstrap.php在Query.php中是这么实例化它的:$config = Container::get('config')->pull('paginate'); /** @var Paginator $class */ $class = false !== strpos($config['type'], '\\') ? $config['type'] : '\\think\\paginator\\driver\\' . ucwords($config['type']); return $class::make($results, $listRows, $page, $total, $simple, $config);$config['type']来自于thinkphp/convention.php配置文件的://分页配置 'paginate' => [ 'type' => 'bootstrap', 'var_page' => 'page', 'list_rows' => 15, ],所以,我们接下来可以自己去创造实例去了。自己创造实例根据以上知识,我们只需要自行实例化Bootstrap类,并将查询的数组数据注入至Bootstrap实例,最后将Bootstrap实例交给ThinkPHP来处理就好了,非常简单。$data_list = UserModel::where($map)->order('sort,role,id desc')->select(); $config = Container::get('config')->pull('paginate'); /* $listRows 每页数量 数组表示配置参数 $simple 是否简洁模式或者总记录数 $config 配置参数 page:当前页, path:url路径, query:url额外参数, fragment:url锚点, var_page:分页变量, list_rows:每页数量 type:分页类名 */ // 原型: // public static function make($items, $listRows, $currentPage = null, $total = null, $simple = false, $options = []) $data_list = Bootstrap::make($data_list,$config['list_rows'],1,15,false,$config);此时,$data_list就拥有了原数组就有了Bootstrap实例的外衣,交给ThinkPHP去处理时,就可以分页了。 Typecho自定义首页文章数量 https://www.codeshif.com/archives/44.html 2021-11-24T14:47:23+08:00 修改typecho首页显示文章的数量:编辑文件 functions.php在末尾添加:/* 自定义首页文章分布数量,如 10 */ function themeInit($archive) { if ($archive->is('index')) { $archive->parameter->pageSize = 10; } } Typecho导航栏输出分类 https://www.codeshif.com/archives/43.html 2021-11-24T14:08:47+08:00 编辑外观文件header.php搜索<?php _e('首页'); ?></a>在空行后面添加<?php $this->widget('Widget_Metas_Category_List')->to($categories); ?> <?php while($categories->next()): ?> <a<?php if($this->is('category', $categories->slug)): ?> class="current"<?php endif; ?> href="<?php $categories->permalink(); ?>" title="<?php $categories->name(); ?>"><?php $categories->name(); ?></a> <?php endwhile; ?>