雪落 ❅ 纤影如梦
首页 网盘 留言 登录
夜露黏寒,层云弄影,烛映帘栊月半弯
浏览量 - 164682 开源系统 - 溯雪v1.0.9
RunTime: 0.0095 s Memory: 665 kb
《溯雪-轻博客系统开发文档》

下载

sxlog: v1.0.8 sxlogv1.0.8

环境要求

PHP版本: PHP: 5.6+ PHP5.6+ 推荐PHP: 8.0+ 推荐PHP8.0+

安装

可以使用宝塔面板来安装,一键PHP环境部署,送你3188元礼包,点我领取

将下载的程序代码解压到你的网站根目录,直接运行你的网站,会自动跳转到安装页面

在安装页面输入相关信息和登录密码,点击提交后会进入首页

警告:本程序严禁用于非法用途,请遵守相关法律法规,使用者因违反本声明的规定而触犯中华人民共和国法律的,一切后果自己负责,本站不承担任何责任。

升级

进入后台,点击网站首页按钮,可查看系统的当前版本号,如果当前版本较低时,会自动弹出新版本更新提示窗,点击更新即可,升级前请做好网站备份,避免升级造成不必要的数据损失。

提示1:系统同步也是更新的一种,会与官网最新的核心文件同步,从而达到系统版本的更新。

提示2:数据库版本同步指的是你当前的数据库版本将与官方最新版本同步,这里的版本主要指的是数据字段结构,系统升级有时候会增加数据库字段,一般在线更新的时候会自动更新,这里的数据库版本并不是指的数据库数据同步哦,官网并不会收集你数据库的数据。

文件结构

┌─index.php   首页入口
│
├─db 数据库
│  ├─article      文章列表数据
│  ├─comment      文章评论数据
│  ├─upload       文章上传数据
│  ├─conf.db      网站配置
│  ├─article.db   文章列表
│  ├─tag.db       标签列表
│  ├─error.db     错误日志列表
│  └─visit.db     访问记录列表
│
├─ext 扩展
│
├─lib 函数类库
│  ├─admin                   后台管理页面
│  │  ├─compile              主题模板编译后的文件存放目录
│  │  ├─article.create.php   文章创建页
│  │  ├─article.editor.php   文章编辑页
│  │  ├─article.php          文章管理页
│  │  ├─ext.php              扩展管理页
│  │  ├─tpl.php              模板管理页
│  │  ├─header.php           模板头部文件
│  │  ├─footer.php           模板尾部文件
│  │  ├─index.php            后台首页
│  │  ├─login.php            后台登录页
│  │  ├─prompt.php           提示页 
│  │  ├─setting.php          基础设置页
│  │  ├─navbar.php           导航设置页
│  │  ├─link.php             友情链接页
│  │  ├─error.php            错误日志页
│  │  └─visit.php            访问记录页
│  │
│  ├─style           公共样式
│  │  ├─common.css   公共样式
│  │  ├─common.js    公共脚本
│  │  ├─fk.css      fk样式
│  │  └─logo.png     系统logo
│  │
│  ├─install.php           系统安装文件
│  ├─common.php            公共方法
│  ├─file.util.class.php   文件操作类
│  ├─fk.class.php          fk标记语言类
│  ├─function.php          函数方法集合
│  ├─theme.class.php       模板编译类
│  ├─upload.class.php      上传类
│  └─vcode.class.php       验证码类
│
└─tpl 主题模板
   └─default
      ├─compile       主题模板编译后的文件存放目录
      ├─style         样式文件夹
      ├─conf.php      模板配置文件
      ├─icon.png      模板缩略图
      ├─header.php    模板头部文件
      ├─footer.php    模板尾部文件
      ├─sidebar.php   模板侧栏文件
      ├─index.php     首页
      ├─search.php    搜索页
      ├─tag.php       标签页
      ├─page.php      详情页
      └─prompt.php    提示页 

主题模板

  • 主题模板用于定制溯雪的界面,为其提供布局效果及样式
  • 主题模板在tpl文件夹下

开发规范

代码的规范在开发中起到事半功倍的作用,拥有良好的设计规范对开发者来说非常有必要,规范的代码可以促进团队合作、减少bug处理、降低维护成本、有助于代码审查等等好处,尽量保持代码的整洁以及格式的对齐,这不仅对我们自己来说更加易读,对别人也是。写注释是个好的编程习惯,所以尽量详细一些,规范一些。

需要注意的是开发主题模板时,尾部文件footer.php中应注明溯雪的版权,指定链接为:https://xueluo.cn/sxlog

主题开发文档

主题模板中应包含以下几个页面

default 主题模板文件夹,名称不能包含中文,不能为纯数字,应放在tpl文件夹中
 │-----------------------------------------------------------
 ├─style  样式文件夹,存放css、js以及图片等文件,不是必须的
 │-----------------------------------------------------------
 ├─main.php      自定义公共文件(非必须)
 ├─header.php    模板公共头部文件(必须)
 ├─footer.php    模板公共尾部文件(必须)
 ├─index.php     首页(必须)
 ├─search.php    搜索页(非必须)
 ├─tag.php       标签页(非必须)
 ├─page.php      详情页(必须)
 ├─prompt.php    错误提示页(必须)
 ├─icon.png      主题的主图(必须)
 └─conf.php      主题的配置文件(必须)

tab.php(标签分类页) 或 search.php(搜索页)不存在时,将默认调用index.php模板

自定义页面和URL链接

如果这些页面并不能满足你的需求,那么你可以通过main.php文件来设置更多的页面,main.php在主题模板中可有可无,如果存在的话,它会被当做公共文件引入到系统中,不管进入任何页面,都会优先执行main.php的代码,所以main.php中不但可以设置更多的页面,引入更多的自定义类库,你甚至可以完全覆盖sxlog自身的页面业务逻辑。

如何编写main.php中的代码呢?我们举个例子,当你需要设置某个自定义的页面时,例如一个demo页面,你想访问的链接是:https://example.com/demo,这个时候demo的页面名称可以通过$page来获得,$page是个全局变量,可以获得网址/后面的第一个参数(sxlog中的url参数是通过/来分割的),有了$page就可以很方便的写demo页面的逻辑,以及引用模板中的demo.php页面,示例如下:

main.php文件

<?php

// demo页面
if($page == 'demo'){
    $info = [
        'title' => '静默的流年',
        'content' => '站在青春的夕阳下,感受着过往,留下浅浅的笑靥,或许这就是青春的流逝吧!'
    ];
    include $tpl->view('demo');
    exit;
}

?>

demo.php文件

<h3> {$info.title} </h3>
<p> {$info.content} </p>

上面的示例是不是很简单?main.php很强大,可以内置任何你想要的功能或页面,上面我们说到了$page这个变量,默认它获取的是URL第1个参数,如果你需要获取第2个、第3个参数,那么你可以通过get()这个方法来获取,在sxlog中,get()用来获取url上的参数,post()用于获取form表单提交过来的参数,这两个方法能帮助你便捷的处理表单操作。

这两个方法位于lib/function.php中,function.php包含了开发者常用的封装函数,具体请查阅该文件,这里不做过多的赘述。

主题中的标签说明

上面的demo.php示例中我们用到了花括号来输出变量内容,这是sxlog内置的模板编写能力,{$info.title}等同于<?php echo $info['title'];?>,当然你也可以将{$info.title}写成{$info['title']}(我想没人会这么费力不讨好),具体请看下面的模板语法。

编写模板时我们常常使用花括号来输出内容,它的工作原理是将你的主题模板编译成php原生格式,编译后的文件会放入当前主题模板的compile文件夹中,所以我们在开发主题模板时不要使用compile文件夹来存放主题文件。

下面是关于模板标签的一下用法。

模板语法

标题语法说明

变量

{$example}

$为前缀

输出其它内容

{#EXAMPLE}

{#time()} {# time()}

{#$example > 10 ? '真' : '假'}

#为前缀,后面可以为常量、方法或php原生语句,#代表输出,会被编译成echo,后面是echo的内容。

插入url链接

{url admin}

{url admin/article}

{url admin/article/editor/$article.id}

url为前缀,后面为网址链接(网站链接前面不能为斜杠),网址中支持使用变量(只能使用变量,不支持常量),这种方式支持伪静态。

举例:{url admin}如果伪静态开启,则链接实际为/admin,伪静态关闭,则链接实际为/?admin

IF判断

{if $example > 10} 内容1 {/if}

{if $example > 10} 内容1 {else} 内容2 {/if}

{if $example > 10} 内容1 {elseif $example > 25} 内容2 {else} 内容3 {/if}

{if $example > 10 : echo '内容'}

{if $example > 10 : $title='hello'}

简单的if语句无需使用括号,多条件判断可以使用。

{if 条件:语句}形式,冒号左边为判断,如果判断为真,则执行右边的语句

循环遍历

{foreach $articleList}
    <p> 条目:{$index} </p>
    <p> KEY:{$key} </p>
    <p> {$item.title} </p>
    <p> {$item.intro} </p>
{/foreach}  

{foreach $articleList as $article}
    <h3> {$article.title} </h3>
    <p> {$article.intro} </p>
{/foreach}  

{foreach $articleList as $name => $article}
    <h3> URL的名称:{$name} </h3>
    <h3> {$article.title} </h3>
    <p> {$article.intro} </p>
{/foreach}  

支持这三种遍历方式,这里请注意,只有第一种foreach方式内置三个变量,分别如下:

$index 表示当前条目,从0开始递增

$key 表示当前数组的Key

$item 表示当前数组的Value

引入模板

{include header}

{include bbs/list}

{include tpl header}

{include admin header}

include 指令常用于引入模板,一处编写,多处引用,降低开发成本。

header 表示为当前目录中的header.php文件。

bbs/list 表示当前目录中bbs文件夹下的list.php文件。

tpl headertpl前缀,表示当前主题模板根目录下的header.php文件,常用于开发前端扩展中的页面编写。

admin headeradmin前缀,表示后台模板主题根目录下的header.php文件,常用于开发后端扩展中的页面编写。

原生语句

{{
    $info = [
        'title' => '静默的流年',
        'content' => '留下浅浅的笑靥,或许这是青春的流逝!'
    ];
    $info['author'] = '闫立峰';
    echo $info['title'];
    echo $info['content'];
    echo $info['author'];
}}  

{{
    $info = [
        'title' => '静默的流年',
        'content' => '留下浅浅的笑靥,或许这是青春的流逝!'
    ];
    $info.author = '闫立峰';
    echo $info.title;
    echo $info.content;
    echo $info.author;
}}  

当我们需要在模板文件中编写很长的php原生代码时,我们可以用两个花括号来写,当然你也可以继续使用原生的<?php ?>来写。

但是,上面的$info.title会被编译成$info['title'],所以说双花括号中写php更加方便,形式更好。

页面变量

全局常量

标签说明

V

系统版本号

ROOT

根目录的绝对路径

HOME

根目录的相对路径

URL

根目录的相对路径与伪静态结合

DB

数据目录的绝对路径

EXT

扩展目录的绝对路径

LIB

类库目录的绝对路径

TPL

当前主题模板的相对路径

TPLPATH

当前主题模板的绝对路径,包含项目的整个路径

TPL_STYLE

当前主题模板的style相对路径

LIB_STYLE

公共style相对路径

LOGIN

登陆状态

CONF

配置信息

DEBUG

0:线上模式(无错)1:调试模式(无错+日志)2:开发模式(报错+日志)

全局变量

标签说明

$host

博客网址

$conf

网站配置信息

$tpl

模板类

$method

请求方式:POST、GET

$ajax

是否为Ajax请求

$ip

ip地址

$page

当前页面(index、tag、search、page、prompt、admin)

$time

当前时间戳

$extList

已安装的扩展列表

$articleList

文章列表

$tagList

分类标签列表

$navbarList

导航菜单列表

$linkList

友情链接列表

页面标签使用

网站配置信息($conf的字段说明)

标签说明

{$conf.title}

网站的title标题

{$conf.name}

网站头部标题

{$conf.intro }

网站描述

{$conf.mood}

心情记录

{$conf.key}

SEO网站关键字

{$conf.desc}

SEO网站描述

{$conf.brief}

新建文章时的描述限制字数

{$conf.password}

网站登录密码

{$conf.tpl}

主题模板

{$conf.compile}

模板自动编译

{$conf.article.paging}

文章分页设置,每页数量

{$conf.article.count}

文章总数量

{$conf.comment.restrict}

评论限制设置,每日限制的条数

{$conf.comment.paging}

评论分页设置,每页数量

{$conf.comment.count}

评论总数量

{$conf.vcode.open}

验证码开启

{$conf.vcode.width}

验证码宽度

{$conf.vcode.height}

验证码高度

{$conf.vcode.length}

验证码字符串数量

{$conf.icp}

ICP备案号

{$conf.views}

网站浏览量

{$conf.blacklist}

IP黑名单

{$conf.rewrite}

伪静态

{$conf.js}

JS脚本代码

{$conf.debug}

等同于全局变量DEBUG

{$conf.install}

系统是否已安装

首页变量

标签说明

{$pageNum}

当前页码,默认为1

{$pageSize}

文章每页条数

{$article}

包含文章列表和分页信息

{$article.count}

文章总数量

{$article.paging}

文章分页的HTML

{$article.list}

文章列表,字段详情请看下面的【文章详情页】

标签分类页

标签说明

{$tab}

标签名

{$pageNum}

当前页码,默认为1

{$pageSize}

文章每页条数

{$article}

包含文章列表和分页信息

{$article.count}

文章总数量

{$article.paging}

文章分页的HTML

{$article.list}

文章列表,字段详情请看下面的【文章详情页】

文章详情页

标签说明

{$article.id}

文章ID

{$article.title}

文章标题

{$article.intro}

文章描述

{$article.img}

文章中的第一张图片

{$article.content}

文章内容

{$article.top}

文章是否置顶

{$article.private}

文章是否为私密

{$article.comment}

文章是否可以评论

{$article.comments}

文章评论数

{$article.views}

文章浏览数

{$article.tag}

文章标签

{$article.time}

文章创建时间

{$article.url}

文章的URL链接

{$comment.count}

当前文章的评论总数

{$comment.list}

当前文章评论列表,字段详情请看下面的【评论板页】

{$comment.html}

当前文章评论列表的HTML

{$comment.paging}

当前文章评论分页的HTML

评论板页($comment.list的字段说明)

标签说明

{$comment.id}

评论ID

{$comment.pid}

父级评论的ID,默认为0

{$comment.admin}

是否为管理员的评论

{$comment.content}

评论内容

{$comment.ip}

评论IP

{$comment.time}

评论时间

主题模板中的扩展标签

<!DOCTYPE html>
<html lang="zh-Hans">
<head>
  <!-- ext.head-header -->
  <title>网站标题</title>
  <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
  <link rel="shortcut icon" href="/lib/style/logo.png"/>
  <link rel="stylesheet" href="/lib/style/common.css"/>
  <!-- ext.css -->
  <script src="/lib/style/common.js"></script>
  <!-- ext.script -->
  <!-- ext.head-footer -->
</head>
<body>
<!-- ext.body-header -->
<!-- ext.body-footer -->
</body>
</html>

开发主题模板过程中,页面请务必保留该6个扩展标签,它以html的注释形式存在,前缀为ext.,它的作用是提供扩展机制的支持,每个扩展标签的位置如下:

<!-- ext.head-header --> 放在head标签中的最上面。

<!-- ext.head-css --> 放在head标签中link标签的下面。

<!-- ext.head-script --> 放在head标签中script标签的下面。

<!-- ext.head-footer --> 放在head标签中的最下面。

<!-- ext.body-header --> 放在body标签的最上面。

<!-- ext.body-footer --> 放在body标签的最下面。

扩展开发

  • 扩展用于定制 sxlog 的功能
  • 扩展在ext文件夹下

扩展开发文档

扩展中应包含以下几个页面

default 扩展文件夹,名称不能包含中文,不能为纯数字,应放在ext文件夹中
 ├─conf.php       配置文件(必须)
 ├─main.php       扩展入口文件
 ├─common.php     扩展公共文件
 ├─admin.php      管理页面文件
 ├─install.php    安装文件
 ├─uninstall.php  卸载文件
 └─icon.png       扩展的图标,300*300(必须)

conf配置文件说明

<?php
  // 配置文件
  return array (
    'id' => '扩展的ID',
    'type' => '应用类型,主题为tpl,扩展为ext',
    'author' => '作者,开发者的账号',
    'name' => '扩展的名称',
    'intro' => '扩展的简述',
    'home' => '扩展的主页',
    'version' => '版本号,格式为1.0.0'
    'content' => '扩展的详细内容'
  );
?>

main文件说明

该文件可有可无,与tpl中的main.php一个概念,用于配置页面路由和业务逻辑,不同的是该文件的权重要高于tplmain.php权重,在sxlog系统中,我们推荐开发独立的功能使用扩展,如果你只是为了丰富页面的多样化,那么建议写在tpl中。

common文件说明

该文件可有可无,common是扩展的公共文件,如果存在该文件,则每个页面都会引用,一般用于操作hook,例如后台添加菜单,那么应当写在common中,而不是main中,这是唯一与main有区别的地方,common的权重要高于main,common适合写hook,main适合写页面路由以及业务逻辑。

admin文件说明

该文件可有可无,admin是扩展的管理页面文件,如果存在该文件,扩展管理中的该扩展中会有管理按钮,点击按钮进入该admin管理页面,一般用于扩展功能所需要的页面,当然,你也可以直接通过main来自定义页面和路由,admin最主要的目的是在扩展列表中显示管理按钮。

install文件说明

该文件可有可无,如果存在该文件,install安装文件会在扩展安装的时候执行一次,一般用于提前创建好数据库之类的操作。

uninstall文件说明

该文件可有可无,如果存在该文件,uninstall卸载文件会在扩展卸载的时候执行一次,一般用于清除扩展造成的数据垃圾。

扩展中引用前端模板和后端模板

如果你想做一个放置于前端页面中的功能页面,通常页面的开发就是引入当前主题的header.phpfooter.php文件,这样打开的页面与主题风格会更加贴近,用户体验更好,那么你的页面中可以这么写:

<?php
  {include tpl header}
  <div class="content">
    <h3>hello world!</h3>
  </div>
  {include tpl footer}
?>

上面的主题标签有对include的详细描述,include后面的tpl代表的是当前主题目录,admin代表的是后端主题目录,所以你如果想做的一个后端扩展的话,那么应该使用{include admin header}{include admin footer}

扩展中给页面插入css样式

//common.php文件
<?php
    //所有页面添加a1样式文件
    hook('css','/ext/demo/style/a1.css');

    //只单独给后台添加a2样式文件
    if($page == 'admin'){
        hook('css','/ext/demo/style/a2.css');
    }
?>

hook钩子的基本使用

扩展应用的是hook钩子机制,具体hook钩子位置请查看lib/admin视图文件的注视标签,以ext为前缀,例如!-- ext.index-top-->,该标签你可以这样来理解,ext为前缀的说明是扩展的hook,点后面的index-top为hook名称,我们可以在页面的这个hook位置插入html,接下来我们写个示例。

<?php
    //后台首页添加一个自定义栏目,例如网站名称
    hook('index-top','<div class="title">网站名称</div><div class="p">'.$conf['title'].'</div>');
?>

hook函数

语法:hook($name, $html)
  • 功能说明:钩子操作
$name  [string] [必填] hook名称
$html  [string|function] 返回值

数据库操作

sxlog中的数据库操作只需要记住db()、dbSave()、dbDelete()、dbUpdate()这四个方法,以下是这些方法的使用说明。

db 查询

语法:db($name, $cond = [], $orderby = [], $page = 0, $pagesize = 0)
  • 功能说明:查询数据
  • 查询成功:如果该数据为数组,则返回数组格式,如果为纯文本,则返回纯文本
  • 查询失败:返回空数组
$name     [string] [必填] 表名
$cond     [array]  [选填] 条件查询
$orderby  [array]  [选填] 排序
$page     [int]    [选填] 页数
$pagesize [int]    [选填] 每页条数

如果该数据库为二维数组,可通过以下条件查询来获取相应的数据

//我们用article表(位于db文件夹中的article.db文件,存放着文章列表数据)来说明db()的用法

//返回文章的所有数据
db('article');

//返回所有被置顶的文章
db('article', ['top' => 1]);

//返回url名称为fk的这篇文章
db('article', ['name' => 'fk']);

//返回所有的文章,并先按照最新的时间排序,再按照置顶排序
db('article', [], ['time' => 1, 'top' => 1]);

//返回文章的第2页数据,条数为30,并先按照最新的时间排序,再按照置顶排序, 
db('article', [], ['time' => 1, 'top' => 1], 2, 30);

//相信以上条件查询可以满足大多数业务了,但仍然无法体现到db()方法的优秀,接下来我们玩玩更高级的`$cond`查询方式
//
//搜索文章标题有`雨烟`两字的所有数据
db('article', ['title' => ['LIKE' => '雨烟']]);

//查询文章浏览量大于100的所有数据,支持> < >= <= ==这五种判断
db('article', ['views' => ['>' => 100]]);

//查询文章拥有`笔记`标签的所有数据,说白了就是针对三维数组的查询,tag字段存储的是数组,而上面的LIKE是用于字段为字符串类型的查询
db('article', ['tag' => ['IN' => '笔记']]);

//返回置顶的文章,且浏览量大于100的所有数据
db('article', ['top' => 1, 'views' => ['>' => 100]]);

dbSave 保存

语法:dbSave($name, $data)
  • 功能说明:保存数据
  • 保存成功:返回写入数据库的字符数
  • 保存失败:返回false
$name     [string]       [必填] 表名
$data     [string|array] [必填] 保存数据
$arr = [
    [
        'title' => '半载浮生',
        'content' => '既不回头,何必不忘。既然无缘,何须誓言。今日种种,似水无痕。明夕何夕,君已陌路。'
    ],
    [
        'title' => '静默的流年',
        'content' => '站在青春的夕阳下,感受着过往,留下浅浅的笑靥,或许这就是青春的流逝吧!'
    ]
];

//如果product表不存在,则会创建
dbSave('product',$arr);

dbInsert 新增

语法:dbInsert($name, $data, $index=true)
  • 功能说明:插入新数据
  • 新增成功:返回true
  • 新增失败:返回false
$name     [string]       [必填] 表名
$data     [string|array] [必填] 插入的新数据
$index    [bool]         [选填] 是否根据索引新增数据
$arr = [
    'title' => '半载浮生',
    'content' => '既不回头,何必不忘。既然无缘,何须誓言。今日种种,似水无痕。明夕何夕,君已陌路。'
];

//在product表中插入一条新数据
dbInsert('product', $arr);

dbDelete 删除

语法:dbDelete($name, $cond=[])
  • 功能说明:删除数据
  • 删除成功:返回true
  • 删除失败:返回false
$name     [string] [必填] 表名
$cond     [array]  [选填] 条件删除,使用方式参考db()的$cond参数
$index    [bool]   [选填] 是否重新索引,数组的key从0开始,默认不重新索引
//删除整个product表数据
dbDelete('product');

//删除product表id字段为1的这条数据
dbDelete('product', ['id' => 1]);

dbUpdate 修改

语法:dbUpdate($name, $cond, $data)
  • 功能说明:修改数据
  • 修改成功:返回true
  • 修改失败:返回false
$name     [string]       [必填] 表名
$cond     [array]        [必填] 条件更新
$data     [string|array] [必填] 更新数据
$arr = [
    'title' => '半载浮生',
    'content' => '既不回头,何必不忘。既然无缘,何须誓言。今日种种,似水无痕。明夕何夕,君已陌路。'
];

//更新product表id字段为1的这条数据
dbUpdate('product', ['id' => 1], $arr);

//更新product表所有数据的top为1
dbUpdate('product', [], ['top' => 1]);

如果数据表demo为一维数组,例如为这样的数据格式

[
    'title' => '这是标题',
    'content' => '今生有缘'
];

那么更新demo表的title字段就可以这样做,第二个参数不再是条件查询,而是指定字段数据更新,第三个参数勿传

dbUpdate('demo', ['title' => '不错,这就是标题']);
评论留言
验证码
一共4条留言