前言:
因为我也是从新手过来的,现在也还只是个菜鸟,所以我帮公司做了一个简单的官网,是按个人博客的形式做的,但是看上去简单,实际上学到的知识点却不少,给了我很多的启发,所以我就复习一下,看看还有没有什么知识漏掉了,也分享一下需要的朋友们。
代码的重复性除了使用公共函数之外,还可以通过继承来解决!
公共函数:适用于参数不一的
继承:全都是一样的
url: onClick="javascript:window.location.href = '{:url('admin/admin/add')}'"
默认模块的绑定:
正常情况下,tp5框架给我们默认访问的是index模块下的index控制器下的index的方法。但是如果你想改变默认模块,只要在配置文件上加上一句代码即可:
// 默认模块名 'default_module' => 'home',
模块绑定:
模块绑定就是通过url只能访问这个模块下的控制器和方法。只要在入口文件配置一下就行
//模块绑定 define('BIND_MODULE','admin');
然后访问方式就是www.tp5/index/index,这样就能访问到admin模块下的index控制器的index方法 (www.tp5.com是访问public下的index的)
当然,还可以再深入一点的绑定,可以绑定到一个控制,只能访问这个控制器下的方法:
//模块绑定 define('BIND_MODULE','admin/index');
然后访问方式就是www.tp5/index,这样就能访问到admin模块下的index控制器的index方法 (www.tp5.com是访问public下的index的)
具体详情请查看慕课网的基础版“入口文件的绑定”
api接口输出应用:
在public下我们创建一个api.php文件。其内容和index.php一样。
然后访问www.tp5/api.php文件,这是api.php和index.php的作用是完全相同的
这是,如果我们要提供一个接口给其他第三方用的话,但是又不希望他访问到我们的其他模块下的数据的话,我们可以在这个文件里使用我上面所说的模块绑定
或者我们在配置文件上配置上一条代码:
// 入口自动绑定模块 'auto_bind_module' => true,
然后我们再访问这个api.php入口文件的时候他就会默认访问到api的这个模块(主要:入口文件名对应模块名,两者的名字要一模一样!),通过这样的配置,也可以达到模块绑定的效果!
模板引入及分离:
- 最基本的调用模板:
return $this -> fetch('控制器名/方法名');
- runtime文件夹(在根目录)是用来缓存文件的。
- 视图的输出替换在配置文件config里配置:
<?php
return [
// 视图输出字符串内容替换
'view_replace_str' => [
"__PUBLIC__" => '/' //表示public目录下
"__STATIC__" => '/static', //表示public/static目录下,可以直接用
];
注意!一切的静态资源都是先从public文件夹里面开始加载的,建议将资源放在public文件夹下,静态资源存放目录(css,js,image)放在public/
static/下。当然如果你想要放到public以外的文件夹,直接调用
ROOT_PATH (可以在config调用)就可以了,这个直接访问到你项目的根目录。但是关于静态资源(css,js,image)还是放在static下比较好。如果你自己要定义常量的话直接到think的文件夹下找base.php文件,全部的框架配置也在同个文件夹下的convention.php文件
4. 公共目录都是自己配置上去的,例如你要配置公共的配置文件的话,你要在入口文件(index.php)那里加一句话
<?php
// [ 应用入口文件 ]
// 定义应用目录
define('APP_PATH', __DIR__ . '/../app/');
//定义配置文件的路径
define('CONF_PATH', __DIR__.'/../conf/');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';
然后在根目录创建一个叫conf的文件夹,然后在文件夹里面创建config.php文件,这个就是我们的公共配置文件。你还可以创建database.php文件,这个就是我们的公共配置数据库文件。你还可以创建模块专用的配置,也是在已经创建好的conf的文件夹下创建一个文件,名称以你的模块名称为主。例如:conf/admin。在模块文件下一样可以创建config和database文件,但是这些文件只对这个模块下产生作用。你也可以直接在模块下给你配置的config配置你的参数,但是为了更方便一点我还是选择了我上面所说的。
5.用include引入文件,可以省掉html里重复的代码。用法是在view里创建一个common的文件夹,里面是你的引入文件。然后在你要引入的地方 {include file='common/name'}即可,如果你在里面也设置了控制器传来的变量,正常在控制器上输出就行。
数据验证及验证场景详解:
<?php
namespace app\admin\validate;
use think\Validate;
class Admin extends Validate
{
//验证的数据
protected $rule = [
'username' => 'require|max:25|unique:admin',
'password' => 'require',
];
//提示信息
protected $message = [
'username.require' => '管理员名称必须填写',
'username.max' => '管理员名称长度不得大于25位',
'username.unique' => '管理员名称不得重复',
'password.require' => '管理员密码必须填写',
];
//验证场景
protected $scene = [
'add' => ['username'=>'require|unique:admin','password'],
'edit' => ['username'=>'require|unique:admin'],
];
}
具体的请查看开发者文档!!!
唯一性验证:
在验证器里面有个验证当前请求的字段值是否为唯一的内置验证规则:
可以判断数据表里存不存在这个字段!!!
tp5链接查询及关联查询详解:
这里有两种方法:
1.数据表操作(join):
Db::table('think_artist')
->alias('a')
->join('think_work w','a.id = w.artist_id')
->join('think_card c','a.card_id = c.id')
->select();
具体请查看开发者手册!
2.模型操作(hasMany or belongsTo),但是不推荐使用,因为比较难理解
参考:http://www.thinkphp.cn/topic/50478.html
hasMany关联
用法:hasMany(‘关联模型’,‘外键’,‘主键’);
除了关联模型外,其它参数都是可选。
关联模型(必须):模型名或者模型类名
外键:关联模型外键,默认的外键名规则是当前模型名+_id
主键:当前模型主键,一般会自动获取也可以指定传入
将第三个参数写成“关联模型的主键“结果出错,改成“当前模型主键“才正确。
主模型会有一个默认的主键 "表名_id" ,关联模型也会有默认的外键 "表名_id".
百度编译器:
下载百度编译器,因为我是用php语言写的,所以剧下载php版的,然后我一般都把全部代码放进去start文件夹的后台静态资源里面,记住哦,是全部哦,包括php文件!
然后我们只要把
<script type="text/javascript" charset="utf-8" src="__ADMIN__/ueditor/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="__ADMIN__/ueditor/ueditor.all.min.js"> </script>
<!--建议手动加在语言,避免在ie下有时因为加载语言失败导致编辑器加载失败-->
<!--这里加载的语言文件会覆盖你在配置项目里添加的语言类型,比如你在配置项目里配置的是英文,这里加载的中文,那最后就是中文-->
<script type="text/javascript" charset="utf-8" src="__ADMIN__/ueditor/lang/zh-cn/zh-cn.js"></script>
这三个文件引入就可以了,然后在html上的使用:
<script id="editor" type="text/plain"></script>
这时候我们还有再写一段JavaScript的代码:
<script type="text/javascript">
var ue = UE.getEditor('editor');
</script>
这样就完成了,如果你想设置内容的话:
<script type="text/javascript">
var ue = UE.getEditor('editor');
var content = '内容';
ue.ready(function() {
ue.setContent(content, true);
});
</script>
这样就完成了!获取的话他会有一个自己的name,不用设置。具体请查看百度编译器的开发者手册!
安装验证码类及完成管理员登录逻辑:
因为验证码需要用到tp5给的扩展包,所以我们这里需要检查一下你的tp5框架有没有这个扩展包,我们打开tp5\vendor\topthink下,看看有没有think-captcha这个文件就行了,如果存在的话,就代表你的tp5框架已经安装了,没有的话你去官网看一下,然后自己下载安装。
如果没有安装的话,请查看开发手册,记得,安装验证码需要定位(cd -> 打开)到你的框架的根目录才发送那个安装的命令,安装的话大概需要10分钟左右。
具体什么使用请查看开发者手册
管理员登录逻辑:
我们先普及一下,cookie是存储在个人电脑上的,session是存储在服务器上的,cookie和session之间是靠着session_id联系和识别的。
所以有些自动获取账号和密码的就是靠着session_id查找来实现的。
普及先到这里。
登录验证呢,我们用Model来进行验证:
无验证码版本:
model:
controller使用:
有验证码版本:
验证码的使用:
model:
controller:
简单权限认证:
到目前为止,我们做的登录验证一点用都没有,为什么呢?
因为别人还是可以绕过你这个登录来访问你的其他后台页面!
所以我们还需要进行最后一步的操作:
我们在公共模块下(common模块)写一个控制器
<?php
namespace app\common\controller;
use think\Controller;
class BaseController extends Controller
{
public function __construct()
{
parent::__construct();
if(!session('session_name'))
{
$this -> error('请登录!','admin/login/index',[],2);
die();
}
//个人资料
$this -> assign('name',session('session_name'));
//分页显示数目
$this->num = 5;
}
}
然后让所有需要通过登录才能访问到的页面控制器都基础这个类就行了。
关于控制器输出数据到模板
我们在控制器输出数据到模板都是用$this -> assign('name','value');这样输出的。
但是如果有多条数据的话我们就要多次调用这个方法,这样不方便,所以:
$this -> assign(
array(
'name' => 'value',
'name' => 'value'
)
);
这样我们就只要调用一次就行了!推荐!
关于热度:
思路:点一下,在某个字段上就自动加1,方法:
调用当前控制器的其他方法;$this -> 方法名();
Tag寻找相类似的搜索:
现在我们要做这样的一个功能,就是根据多个标签来查找相关信息。多个标签是用中文逗号来隔开的,所以:
$keywords参数就是标签数据,是一个字符串来的,$id是文章id。
我们将字符串拆分成多个字段之后通过循环多个标签,获取相关内容,$map['id'] = ['neq',$id];是防止把当前文章也放上去。
因为其他文章也是有多个标签,所以同一篇文章会被重复多次,所以我们要将多余重复的进行排除。
然后我做了一个详细的测试:
static $database = [
array('id' => 1,'key' => '测试', 'value' =>'我是测试一','tal' =>'美食,小楼人家'),
array('id' => 2,'key' => '测试', 'value' =>'我是测试二','tal' =>'风景'),
array('id' => 3,'key' => '测试', 'value' =>'我是测试三','tal' =>'美女'),
array('id' => 4,'key' => '测试', 'value' =>'我是测试四','tal' =>'租房'),
array('id' => 1,'key' => '测试', 'value' =>'我是测试一','tal' =>'美食,小楼人家'),
];
public function index()
{
$where = array();//数据
$key = array();//键值存储
foreach($this::$database as $k => $v)
{
//----储存键值----
foreach($v as $kk => $vv)
{
$key[] = $kk;
}
//--------
$ar = join(',',$v);// 把数组元素组合为一个字符串
$where[$k] = $ar;
}
$where = array_unique($where);//移除数组中重复的值(只能用于一维数组)
dump($where);//已经去除重复了
//从二维数组变成了一维数组(以上)
/*
* array(4) {
[0] => string(46) "1,测试,我是测试一,美食,小楼人家"
[1] => string(31) "2,测试,我是测试二,风景"
[2] => string(31) "3,测试,我是测试三,美女"
[3] => string(31) "4,测试,我是测试四,租房"
}
* */
$key = array_splice($key,count($key)-4);
dump($key);
/*
* 存储键值
* array(4) {
[0] => string(2) "id"
[1] => string(3) "key"
[2] => string(5) "value"
[3] => string(3) "tal"
}
* */
$whered = array();
foreach($where as $k => $v)
{
$whered[$k] = explode(',',$v);//字符串打散为数组
}
// dump($whered);
/*
* array(4) {
[0] => array(4) {
[0] => string(1) "1"
[1] => string(6) "测试"
[2] => string(15) "我是测试一"
[3] => string(21) "美食,小楼人家"
}
[1] => array(4) {
[0] => string(1) "2"
[1] => string(6) "测试"
[2] => string(15) "我是测试二"
[3] => string(6) "风景"
}
[2] => array(4) {
[0] => string(1) "3"
[1] => string(6) "测试"
[2] => string(15) "我是测试三"
[3] => string(6) "美女"
}
[3] => &array(4) {
[0] => string(1) "4"
[1] => string(6) "测试"
[2] => string(15) "我是测试四"
[3] => &string(6) "租房"
}
}
* */
$whereds = array();
$wheredss =array();
foreach($whered as $k => &$v )
{
foreach($v as $kk => &$vv)
{
$whereds[$key[$kk]] = $vv;
};
$wheredss[] = array($whereds);
}
dump($wheredss);
/*
* array(4) {
[0] => array(1) {
[0] => array(4) {
["id"] => string(1) "1"
["key"] => string(6) "测试"
["value"] => string(15) "我是测试一"
["tal"] => string(21) "美食,小楼人家"
}
}
[1] => array(1) {
[0] => array(4) {
["id"] => string(1) "2"
["key"] => string(6) "测试"
["value"] => string(15) "我是测试二"
["tal"] => string(6) "风景"
}
}
[2] => array(1) {
[0] => array(4) {
["id"] => string(1) "3"
["key"] => string(6) "测试"
["value"] => string(15) "我是测试三"
["tal"] => string(6) "美女"
}
}
[3] => array(1) {
[0] => array(4) {
["id"] => string(1) "4"
["key"] => string(6) "测试"
["value"] => string(15) "我是测试四"
["tal"] => string(6) "租房"
}
}
}
* */
}
对于url上参数重复的问题:
有些做了搜索时需要通过url传递参数,然后按下一页的时候参数会在url上重复了,关于这个问题,我们可以这样:
修改前:
修改后:
具体观看:‘32-问题纠正及tags标签完成 【项目完结】’