xml标签库标签-Request类-链式操作-博客实战分类搜索
1、练习视图的XML 标签 2、练习请求Request类 3、练习数据库链式操作 4、博客实战,分类和搜索功能完成
- 安装多应用(tpboke目录)
composer require topthink/think-multi-app
1. 练习视图的XML
- app\index\controller\index.php
namespace app\index\controller;
use think\facade\Db;
use app\BaseController;
use think\facade\View;
use think\facade\Request;
class Index extends BaseController
{
public function index()
{
view::assign('list_name', [
['id' => 1, 'name' => 'one'],
['id' => 2, 'name' => 'two'],
['id' => 3, 'name' => 'three']
]);
view::assign('id', 2);
return view::fetch('demo');
}
}
- app\index\view\demo.html
body
添加
foreach $list_name as $key => $vo<br />
{foreach $list_name as $key => $vo}
key={$key} id={$vo.id} name={$vo.name}<br />
{/foreach}
<br />
volist name='list_name' id='vo' key='key' empty='nothing' offset='1' length='1'<br />
{volist name='list_name' id='vo' key='key' empty='nothing' offset='1' length='1'}
key={$key} id={$vo.id} name={$vo.name}<br />
{/volist}
<br />
for<br />
{for start='1' end='5' step='2' name='i'}
{$i}
{/for}
<br /><br />
if<br />
{if in_array('two', array_column($list_name, 'name'))}
has two
{elseif in_array('three', array_column($list_name, 'name')) /}
has three
{else /}
no two
{/if}
<br /><br />
empty<br />
{empty name='list_name'}
yes empty
{else /}
not empty
{/empty}
<br /><br />
in<br />
{in name='id' value='1,2,3'}
{$id} in
{else /}
nothing
{/in}
<br /><br />
present<br />
{present name='ids'}
$ids存在
{else /}
$ids不存在
{/present}
<br /><br />
defined<br />
{defined name='NAME'}
NAME 常量已定义
{else /}
NAME 常量未定义
{/defined}
2. 练习请求Request类
$req['id'] = Request::get('id', 'default');
$req['name'] = Request::param('name', 'default');
// a 转数组 d 整数 f 浮点 s 字符串 b 布尔
$req['arr'] = Request::param('name/a', 'default');
$req['get'] = Request::input();
$req['post'] = Request::post();
// 控制器和方法
$req['controller'] = Request::controller();
$req['action'] = Request::action();
$req['baseUrl'] = Request::baseUrl();
$req['baseFile'] = Request::baseFile();
halt($req);
3. 练习数据库链式操作
$map = [];
$map[] = ['status', '=', 1];
$map[] = ['id', '<', 4];
$map[] = ['img', 'like', '%/upload/%'];
$res = Db::table('boke')->where($map)->field(['id', 'title', 'img'])->order('id', 'desc')->select()->toArray();
halt($res);
4. 博客实战,分类和搜索功能完成
1. 静态布局文件,博客实战
- 控制器和静态视图准备
- 控制器 app\index\controller\index.php
namespace app\index\controller;
use think\facade\Db;
use app\BaseController;
use think\facade\View;
use think\facade\Request;
class Index extends BaseController
{
public function index()
{
return view::fetch();
}
}
- 视图(继承基础模板) app\index\view\index\index.html
{extend name='public/base'/}
{block name='archive'}
{__BLOCK__}
{/block}
<!-- 列表 -->
{block name='list'}
{__BLOCK__}
{/block}
<!-- 分页 -->
{block name='pages'}
{__BLOCK__}
{/block}
<!-- 侧栏模块 -->
{block name='side'}
{__BLOCK__}
{/block}
- app\index\view\public\base.html 基础模板
{include file='public/header'/}
<div class="container">
<div class="row">
<!-- 左侧列表 -->
<div class="col-md-8">
<div class="panel panel-default">
{block name='archive'}
<div class="panel-heading">Panel heading without title</div>
{/block}
<div class="panel-body">
<!-- 列表 -->
{block name='list'}
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-body">
<div class="row">
<div class="col-sm-3 col-md-3">
<a href="#" class="thumbnail">
<img style="width:100%;max-height:110px;"
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTkyIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDE5MiAyMDAiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjwhLS0KU291cmNlIFVSTDogaG9sZGVyLmpzLzEwMCV4MjAwCkNyZWF0ZWQgd2l0aCBIb2xkZXIuanMgMi42LjAuCkxlYXJuIG1vcmUgYXQgaHR0cDovL2hvbGRlcmpzLmNvbQooYykgMjAxMi0yMDE1IEl2YW4gTWFsb3BpbnNreSAtIGh0dHA6Ly9pbXNreS5jbwotLT48ZGVmcz48c3R5bGUgdHlwZT0idGV4dC9jc3MiPjwhW0NEQVRBWyNob2xkZXJfMTc5YjM4ZDIyNTEgdGV4dCB7IGZpbGw6I0FBQUFBQTtmb250LXdlaWdodDpib2xkO2ZvbnQtZmFtaWx5OkFyaWFsLCBIZWx2ZXRpY2EsIE9wZW4gU2Fucywgc2Fucy1zZXJpZiwgbW9ub3NwYWNlO2ZvbnQtc2l6ZToxMHB0IH0gXV0+PC9zdHlsZT48L2RlZnM+PGcgaWQ9ImhvbGRlcl8xNzliMzhkMjI1MSI+PHJlY3Qgd2lkdGg9IjE5MiIgaGVpZ2h0PSIyMDAiIGZpbGw9IiNFRUVFRUUiLz48Zz48dGV4dCB4PSI3MC4wNDY4NzUiIHk9IjEwNC40NDM3NSI+MTkyeDIwMDwvdGV4dD48L2c+PC9nPjwvc3ZnPg=="
alt="...">
</a>
</div>
<div class="col-sm-9 col-md-9">
<h3 style="margin-top: 0;">Thumbnail label</h3>
<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id
elit non mi porta gravida at eget metus. Nullam id dolor id nibh
ultricies.</p>
<p><a href="#" class="btn btn-primary" role="button">Button</a></p>
</div>
</div>
</div>
</div>
</div>
</div>
{/block}
<!-- 分页 -->
{block name='pages'}
<div class="row">
<div class="col-md-12 text-center">
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
<li><a href="#">5</a></li>
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
{/block}
</div>
</div>
</div>
<!-- 右侧侧栏 -->
<div class="col-md-4">
{block name='side'}
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Panel title</h3>
</div>
<div class="panel-body">
<!-- Panel content -->
<div class="list-group">
<a href="#" class="list-group-item active">Cras justo odio<span class="badge"></span></a>
<a href="#" class="list-group-item">Dapibus ac facilisis in<span class="badge"></span></a>
<a href="#" class="list-group-item">Morbi leo risus<span class="badge"></span></a>
<a href="#" class="list-group-item">Porta ac consectetur ac<span class="badge"></span></a>
<a href="#" class="list-group-item">Vestibulum at eros<span class="badge"></span></a>
</div>
</div>
</div>
{/block}
</div>
</div>
</div>
{include file='public/footer'/}
- app\index\view\public\header.html 公共头部
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{$title|default="tpboke bootstrap"}</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css" integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
</head>
<body>
<!-- 导航 -->
<nav class="navbar navbar-default navbar-static-top">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<!-- 导航 -->
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<!-- 搜索 -->
<form class="navbar-form navbar-right">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search" name="search" value="" required="required" />
<span class="input-group-btn"><button type="submit" class="btn btn-default"><i class="glyphicon glyphicon-search"></i></button>
</span>
</div>
</div>
</form>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container-fluid -->
</nav>
<!-- 面包屑 -->
<div class="container">
<div class="row">
<div class="col-md-12">
<ol class="breadcrumb">
<li><a href="#">Home</a></li>
<li><a href="#">Library</a></li>
<li class="active">Data</li>
</ol>
</div>
</div>
</div>
- app\index\view\public\header.html 公共底部
<div class="container">
<div class="row">
<div class="col-md-12">
<p>© 2021 Company, Inc.</p>
</div>
</div>
</div>
</body>
</html>
- 运行 bootstrap 完成静态布局博客图
2. 分类和搜索功能完成
准备工作
- 分类导入数据
CREATE TABLE `cat` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL COMMENT '分类名',
`sort` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '排序',
`status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态 1开启 0关闭',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
INSERT INTO `cat` VALUES ('1', 'Layui', '0', '1');
INSERT INTO `cat` VALUES ('2', 'PHP', '0', '1');
INSERT INTO `cat` VALUES ('3', 'ThinkPHP', '0', '1');
INSERT INTO `cat` VALUES ('4', '前端', '0', '1');
INSERT INTO `cat` VALUES ('5', '小程序', '0', '1');
INSERT INTO `cat` VALUES ('6', '服务器', '0', '1');
- 创建模型
- 创建博客文章模型 app\index\model\Boke.php
namespace app\index\model;
use think\Model;
class Boke extends Model
{
protected $pk = 'id';
protected $name = 'boke';
// 模型字段
protected $schema = [
'id' => 'int',
'title' => 'string',
'img' => 'string',
'content' => 'string',
'date' => 'date',
'cat' => 'int',
'num' => 'int',
'hot' => 'int',
'status' => 'int'
];
// 获取器
public function getStatusAttr($value)
{
$status = [-1 => '删除', 0 => '禁用', 1 => '正常', 2 => '待审核'];
return $status[$value];
}
}
- 创建博客分类模型 app\index\model\Cat.php
namespace app\index\model;
use think\Model;
class Cat extends Model
{
protected $pk = 'id';
protected $name = 'cat';
// 模型字段
protected $schema = [
'id' => 'int',
'name' => 'string',
'sort' => 'int',
'status' => 'int'
];
}
- 创建博客控制器 app\index\controller\index.php
namespace app\index\controller;
use think\facade\Db;
use app\BaseController;
use think\facade\View;
use think\facade\Request;
use app\index\model\Boke;
use app\index\model\Cat;
class Index extends BaseController
{
public function index()
{
$map[] = ['status', '=', 1];
$archive = '最新文章';
// 导航
$catList = Cat::where($map)->select();
view::assign('CatList', $catList);
// 热门输出
$hotList = Boke::where($map)->order('num', 'desc')->limit(5)->select();
view::assign('hotList', $hotList);
// 分类列表
$cat = Request::get('cat/d', 0);
view::assign('cat', $cat);
if ($cat) {
$map[] = ['cat', '=', $cat];
$archive = Cat::where('id', $cat)->value('name');
}
// 搜索列表
$search = Request::get('search', '');
view::assign('search', $search);
if ($search) {
$map[] = ['title|content', 'like', "%{$search}%"];
$archive = '搜索结果';
}
// 详情页
$p = Request::get('p/d', 0);
view::assign('p', $p);
if ($p) {
$map[] = ['id', '=', $p];
$archive = '';
// 阅读数自增
Boke::where('id', $p)->inc('num')->update();
}
view::assign('archive', $archive);
// 渲染输出
$artList = Boke::where($map)->order('id', 'desc')->paginate([
'list_rows' => 2, // 分页2条每页
'query' => Request::param()
]);
view::assign('artList', $artList);
return view::fetch();
}
}
- 修改模型
- 修改渲染分类 app\index\view\public\header.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{$title|default="tpboke bootstrap"}</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css" integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
</head>
<body>
<!-- 导航 -->
<nav class="navbar navbar-default navbar-static-top">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{:url('/')}">Brand</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<!-- 导航 -->
<ul class="nav navbar-nav">
{volist name='CatList' id='vo' key='k'}
<li{if $vo.id === $cat || ($cat === 0 && $k === 1)} class="active"{/if}><a href="{:url('/', ['cat' => $vo.id])}">{$vo.name}</a></li>
{/volist}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<!-- 搜索 -->
<form class="navbar-form navbar-right">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search" name="search" value="{$search}" required="required" />
<span class="input-group-btn"><button type="submit" class="btn btn-default"><i class="glyphicon glyphicon-search"></i></button>
</span>
</div>
</div>
</form>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container-fluid -->
</nav>
<!-- 面包屑 -->
<div class="container">
<div class="row">
<div class="col-md-12">
<ol class="breadcrumb">
<li><a href="#">Home</a></li>
<li><a href="#">Library</a></li>
<li class="active">Data</li>
</ol>
</div>
</div>
</div>
- 渲染主体,模板继承中实现 app\index\view\index\index.html
{extend name='public/base'/}
{block name='archive'}
{if $archive}
<div class="panel-heading">{$archive}</div>
{/if}
{/block}
<!-- 列表 -->
{block name='list'}
{volist name='artList' id='vo' empty="暂无数据"}
<div class="row">
<div class="col-md-12">
{if $p}
<h1>{$vo.title}</h1>
<p><span class="glyphicon glyphicon-time" aria-hidden="true"></span> {$vo.date} <span
class="glyphicon glyphicon-eye-open" aria-hidden="true"></span> {$vo.num}</p>
<p>{$vo.content|raw}</p>
{else /}
<div class="panel panel-default">
<div class="panel-body">
<div class="row">
{if $vo.img}
<div class="col-sm-3 col-md-3">
<a href="{:url('/', ['p' => $vo.id])}" title="{$vo.title}" class="thumbnail">
<img alt="{$vo.title}" style="width:100%;max-height:110px;" src="{$vo.img}"
alt="{$vo.title}">
</a>
</div>
{/if}
<div{if $vo.img} class="col-sm-9 col-md-9" {else/} class="col-sm-12 col-md-12" {/if}>
<h3 style="margin-top: 0;"><a href="{:url('/', ['p' => $vo.id])}"
title="{$vo.title}">{$vo.title}</a></h3>
<p>{$vo.content|mb_strimwidth=0,110,'...','utf-8'}</p>
<p><a href="{:url('/', ['p' => $vo.id])}" rel="nofollow" title="Reamd more"
class="btn btn-primary" role="button">Read more...</a></p>
</div>
</div>
</div>
</div>
{/if}
</div>
</div>
{/volist}
{/block}
<!-- 分页 -->
{block name='pages'}
{empty name='p'}
<div class="row">
<div class="col-md-12 text-center">
<nav aria-label="Page navigation">
{$artList|raw}
</nav>
</div>
</div>
{/empty}
{/block}
<!-- 侧栏模块 -->
{block name='side'}
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">热门文章</h3>
</div>
<div class="panel-body">
<!-- Panel content -->
<div class="list-group">
{volist name='hotList' id='vo' empty='暂无记录'}
<a href="{:url('/', ['p' => $vo.id])}"
class="list-group-item{if $p === $vo.id} active{/if}">{$vo.title}<span
class="badge">{$vo.num}</span></a>
{/volist}
</div>
</div>
</div>
{/block}
- 运行调试
- 首页运行
- 分类页和分页
- 搜索和分页
- 内容页查看