TP常用知识
TP 常用知识
1.composer
################################################## # composer 是 PHP 中用来管理依赖关系的工具 # composer 是一个工具,是为 PHP 项目准备的软件管家 # 官网网址:https://getcomposer.org/ # 中文网址:http://www.phpcomposer.com/ # composer资源仓库或应用市场 # 网址:https://packagist.org/ # thinkphp5.1 需要最低的 PHP 版本为 PHP >= 5.6.0 ######################### # windows 设置 PHP 环境变量(windows 10) ######################### # 查看 PHP 版本 # 命令行窗口 php -v ######################### # 开启相关php扩展 # 修改文件 php.ini extension=php_openssl.dll extension=php_pdo_mysql.dll extension=php_mbstring.dll extension=php_fileinfo.dll extension=php_curl.dll extension=php_gd2.dll extension=php_soap.dll extension=php_mysqli.dll extension=php_sockets.dll [可选] ######################### # 查看命令行下可用扩展 php –m php –m | findstr gd ######################### # 安装 composer # 下载 composer.phar: https://getcomposer.org/download/ # 把下载好的 composer.phar 文件复制到 PHP 环境变量指定的目录中 # 命令创建 bat 文件 echo @php "%~dp0composer.phar" %*>composer.bat # 检查 composer 是否安装成功 composer ######################### # 切换 composer 镜像 # 以管理员身份打开 cmd 命令行窗口(windows用户)或控制台(Linux、Mac 用户)并执行如下命令 # 执行完毕,源切换为国内镜像,下载的速度会有所提升 composer config -g repo.packagist composer https://mirrors.aliyunc.com/composer/ # 备选方案 composer config -g repo.packagist composer https://packagist.laravel-china.org
2.安装Thinkphp
################################################## # ThinkPhp 5.1 环境要求 # 1. PHP >= 5.6.0 # 2. PDO PHP Extension # 3. MBstring PHP Extension ################################################## # 通过 composer 安装 ThinkPhp 5.1 # composer --> 表示执行composer程序 # create-project --> 通过composer去创建项目 # topthink/think --> 框架的名称 # --prefer-dist --> 优先下载压缩包方式,而不是直接从github上下载源码 composer create-project topthink/think=5.1.* tp5 composer create-project --prefer-dist topthink/think=5.1.* tp5
3.目录结构
################################################## # 目录结构 # 1.application 应用目录,如: 前台模块和后台模块都放在此目录,MVC 就在此目录 # 1.1.application/common 公共模块目录,在 application 可以自定创建自己的模块,但在 coommon 定义的函数和模型都是公用的 # 1.2.application/common.php 公共函数库文件 # 1.3.application/[index或admin] 表示 index 模块 和 admin 模块 [自定义创建的] # 2.config 应用配置目录 如: 数据库配置和项目配置都在此目录下的文件中 # 2.1.config/app.php 应用主配置文件 # 3.extend # 4.public 应用 Web 虚拟主机指向的目录 # 5.route 路由定义目录 # 6.runtime 框架自动生成的目录,可以删除 # 7.thinkphp tp 框架目录 # 8.vendor 第三方类库目录,由 composer 管理不要手动操作此目录 # 9.composer.json 此项目的 composer 配置文件 # 10.think thinkphp 提供的命令行工具
4.命令规范
https://www.kancloud.cn/thinkphp/php-fig-psr/3141
5.请求的生命周期

6.路由
///////////////////////////////////////////////////////////////////////////////////////////
// 路由相关配置
// 在 config/app.php 配置文件设置
// 在开发时 pathinfo 和自定义路由,尽量两者用其一
// 如果用自定义路由,则开启设置 route_complete_match 为 true
// 1.强制路由
// 注:将开启强制使用路由,这种方式下面必须严格给每一个访问地址定义路由规则(包括首页),否则将抛出异常。
'url_route_must' => true,
// 2.路由缓存
// 对于路由规则较多的应用可以大幅提升路由性能(仅部署模式有效)
// 注:如果路由定义中,有某个路由规则的路由地址使用了闭包的方式,那么路由缓存将会失效。
'route_check_cache' => true,
// 3.完全匹配
'route_complete_match' => true,
////////////////////////////////////////////////////////////////////////////////////////
// 定义路由
// 路由文件的位置:项目目录 /routes/route.php 文件中进行如下格式的定义
// 注:给控制器方法设置好了请求的路由规则后,原来的pathinfo请求则失效,请求就会报异常,只能通过自定义路由规则来请求
Route::请求方式('路由表达式',匿名函数);
Route::请求方式('路由表达式','[@]模块名/控制器名/方法名'); # 后讲到控制器时使用
////////////////////////////////////////////////////////////////////////////////////////
// 请求类型
// 测试定义好的请求路由规则类型,使用 postman 软件来测试
Route::get('new/:id','News/read'); // 定义GET请求路由规则 查询
Route::post('new/:id','News/update'); // 定义POST请求路由规则 添加
Route::put('new/:id','News/update'); // 定义PUT请求路由规则 修改
Route::delete('new/:id','News/delete'); // 定义DELETE请求路由规则 删除
Route::any('new/:id','News/read'); // 所有请求都支持的路由规则 框架提供 不推荐
////////////////////////////////////////////////////////////////////////////////////////
// 路由参数
// 必填参数
Route::请求方式('路由表达式/:参数',匿名函数);
// 可选参数
Route::请求方式('路由表达式/[:参数]',匿名函数);
Route::get('dd/:id', function (int $id) {
return '我的参数是:' . $id;
});
Route::get('dd/:ids', function (int $ids) {
return '我的参数是:' . $ids;
})->pattern(['id' => '\d+']);
Route::get('dd/[:id]', function ($id = 0) {
return '我的参数是:' . $id;
});
////////////////////////////////////////////////////////////////////////////////////////
// 路由分组
// 路由分组功能允许把相同前缀的路由定义合并分组,这样可以简化路由定义,并且提高路由匹配的效率。
Route::group('分组名(字符串)或者分组路由参数(数组)','分组路由规则(数组或者闭包)');
Route::group(['method' => 'get'], function () {
Route::get('login', function () {
return '用户登录';
});
Route::get(':id', function (id) {
return '退出' . $id;
});
})->pattern(['id' => '\d+']);
Route::group(['method' => 'get'], function () {
Route::group('admin', function () {
Route::get('login', function() {
return '用户登录';
});
Route::get(':id', function($id) {
return '退出' . $id;
});
});
})->pattern(['id' => '\d+']);
7.控制器
///////////////////////////////////////////////////////////////////////////////////////////
// 控制器的后缀
// 打开配置文件 application/app.php,有如下配置
// 表示默认情况下,控制器无特殊后缀。例如 Index控制器,文件名为 Index.php
'controller_suffix' => false,
// 如果需要进行设置,可以设置为
// 表示控制器以Controller为后缀。例如Index控制器,文件名为IndexController.php
// 注:一般不建议进行修改,保持默认,框架默认给我们的配置
'controller_suffix' => 'Controller',
///////////////////////////////////////////////////////////////////////////////////////////
// 使用命令行创建分组
php think build --module 分组名称
///////////////////////////////////////////////////////////////////////////////////////////
// 创建控制器
// 创建控制器的方式有两种
// 如果创建时,没有在模块名称,则默认创建到公共模块中 【common】
// 1.手动创建
// application/模块目录/controller/目录下
// 命名规则:控制器名称(首字母大写) + (控制器后缀,默认没有) + .php
// 2.命令行方式创建【推荐】
// 参数说明
// --plain 标准控制器 (默认创建的控制器是一个资源控制器,所以一般加上此选项)
php think make:controller --plain 模块名/控制器名
php think make:controller --plain index/Demo
////////////////////////////////////////////////////////////////////////////////////////
// 开启调试模式
// 默认情况下,错误描述比较模糊,不方便进行错误调试。这种模式通常叫做“部署模式”。
// 开发阶段可以将框架设置为调试模式,便于进行错误调试:
// 方法1: 修改项目目录 config/app.php文件
'app_debug' => true
'app_trace' => true,
// 方法2: 实际开发中,使用第2种方案
// 在项目下新建文件 .env
// 在文件 .env 添加内容
APP_DEBUG=true
APP_TRACE=true
////////////////////////////////////////////////////////////////////////////////////////
// 前置操作
// 可以为某个或者某些操作指定前置执行的操作方法
// 设置 beforeActionList 属性可以指定某个方法为其他方法的前置操作
// 数组键名为需要调用的前置方法名,无值的话为当前控制器下所有方法的前置方法。
namespace app\index\controller;
use think\Controller;
class Demo extends Controller {
// 前置操作方法列表
protected $beforeActionList = [
// 要触发的方法 => 请求的方法,请求此方法,触发前面定义的方法
'checkUser' => ['index', 'welcome']
];
public function index()
{
return 'demo/index';
}
protected function checkUser()
{
echo '<hr>aaaa';
}
protected function welcome()
{
echo '<hr>bbbb';
}
}
////////////////////////////////////////////////////////////////////////////////////////
// 页面跳转
// 在应用开发中,经常会遇到一些带有提示信息的跳转页面
// 例如操作成功或者操作错误页面,并且自动跳转到另外一个目标页面。
// 系统的 \think\Controller 类内置了两个跳转方法 success 和 error,用于页面跳转提示。
// 普通方式
return $this->success('登录成功!', '/index/demo/su');
return $this->error('我错了');
// 生成 url 地址函数
// 同控制器下面可以直接写方法名
return $this->success('登录成功!', url('su'));
// 不同的控制器下面写控制器名、方法名
// return $this->success('登录成功!', url('index/index', '', false));
// 自定义路由
return $this->success('登录成功!', url('indexR'), ['status' => 1]);
8.请求
///////////////////////////////////////////////////////////////////////////////////////////
// 当浏览器向Web服务器发出请求时,它向服务器传递了一个数据块,也就是请求信息。
// 在Thinkphp5.1中,获取请求对象数据,是由think\Request类负责,
// 在很多场合下并不需要实例化调用,通常使用依赖注入即可,
// 在其它场合(例如模板输出等)则可以使用 think\facade\Request 静态类操作
Request::param('name');
$request->param('name');
////////////////////////////////////////////////////////////////////////////////////////
// 变量获取
// 变量类型方法('变量名/变量修饰符','默认值','过滤方法')
//////////////////////////////////////////////////////////////////////////////////////// // 路由
Route::get('req', '@index/index/req')->name('index/index/req');
Route::post('req', '@index/index/req')->name('index/index/req');
Route::put('req', '@index/index/req')->name('index/index/req');
Route::delete('req', '@index/index/req')->name('index/index/req');
Route::group(['prefix'=>'@index/index/'], function() {
Route::get('req2', 'req2')->name('index/index/req2');
Route::post('req2', 'req2')->name('index/index/req2');
Route::put('req2', 'req2')->name('index/index/req2');
Route::delete('req2', 'req2')->name('index/index/req2');
});
////////////////////////////////////////////////////////////////////////////////////////// 控制器
// 门面的方式
// 第一种方式 门面方式获取数据
// GET 的获取
echo Request::get('id');
// 如果没有则使用默认值
echo Request::get('age', 20);
echo Request::get('age', 20, 'intval');
// 获取 get 全部数据
dump(Request::get());
// 判断一个 key 是否存在
dump(Request::has('sex'));
// 获取指定的数据 白名单
dump(Request::only(['id', 'age']));
// 排除不要的数据 黑名单
dump(Request::except(['id']));
// POST 的获取
dump(Request::post('name'));
// PUT 获取
dump(Request::put('name'));
// DELETE 获取
dump(Request::delete('name'));
// 获取任意类型
dump(Request::param('name'));
// 获取请求的类型
dump(Request::isPost());
dump(Request::isGet());
dump(Request::isPut());
dump(Request::isDelete());
// 获取是否 ajax 请求
dump(Request::isAjax());
// $_SERVER 一样的
dump(Request::server());
// 获取环境变量,说白了就是框架定义好的常量
dump(Request::env());
// 获取路由
dump(Request::route());
////////////////////////////////////////////////////////////////////////////////////////
// 依赖注入方式获取【推荐】
// 第二种方式 依赖注入方式[推荐]
dump($request->get('name'));
dump($request->has('sex'));
dump($request->only(['id']));
dump($request->except(['id']));
////////////////////////////////////////////////////////////////////////////////////////
// 辅助函数【推荐】
// 第三次方式 辅助函数 [推荐]
// 获取全部参数
dump(input(''));
// 获取 GET 的全部参数
dump(input('get.'));
// 获取指定的数据
dump(input('get.id'));
dump(input('get.sex', '女士'));
// 获取 POST 的数据
dump(input('post.'));
// 获取任意类型的请求
dump(input('param.'));
// 获取任意类型的 key 为 name 的值,如果 get 和 post 优先 post
dump(input('name'));
// 判断一个 key 是否存在
dump(input('?sex'));
// 使用变量修饰符 a 数组 s 字符串 d 数字
dump(input('name/d'));
////////////////////////////////////////////////////////////////////////////////////////
// 参数绑定
// 参数绑定是把当前请求的路由参数作为操作方法的参数直接传入,
// 参数绑定并不区分请求类型。
// 链式操作
// 路由
Route::get('req3/:id', '@index/index/req3')->name('index/index/req3')->pattern(['id'=>'\d+']);
Route::get('req3/[:id]', '@index/index/req3')->name('index/index/req3');
// 控制器
public function req3(int $id = 0)
{
// 输出响应
return '参数为:'.$id;
}
////////////////////////////////////////////////////////////////////////////////////////
// 依赖注入
// 依赖注入是一种软件设计思想,在传统软件中,上层代码依赖于下层代码,
// 当下层代码有所改动时,上层代码也要相应进行改动,因此维护成本较高。
// 而依赖注入原则的思想是,上层不应该依赖下层,应依赖接口。
// 意为上层代码定义接口,下层代码实现该接口,从而使得下层依赖于上层接口,
// 降低耦合度,提高系统弹性。
// 控制反转【IOC】
// 依赖注入【DI】
// PHP 7 取消 mysql 扩展 推荐 pdo 不推荐 mysqli
class Db
{
public function query()
{
return 'query';
}
}
class Paginate
{
public function page()
{
return 'page';
}
}
class Vcode
{
public function code()
{
return 'code';
}
}
class Controller
{
/*public function index()
{
$db = new Database();
$page = new Paginate();
$code = new Vcode();
echo $db->query().'----'.$page->page().'----'.$code->code();
}*/
private $db;
private $page;
private $code;
public function __construct($db, $page, $code)
{
$this->db = $db;
$this->page = $page;
$code->code = $code;
}
public function index($db, $page, $code)
{
echo $db->query().'----'.$page->page().'----'.$code->code();
}
}
// php 5.4 提供的反射
$db = new Db();
$page = new Paginate();
$code = new Vcode();
(new Controller())->index($db, $page, $code);
9.响应
///////////////////////////////////////////////////////////////////////////////////////////
// 输出响应
return 'PHP是世界上最好的语言';
///////////////////////////////////////////////////////////////////////////////////////////
// json 数据返回
// 由于默认是输出Html输出,所以直接以html页面方式输出响应内容,
// 但也可以设置默认输出为json格式 config/app.php
'default_return_type' => 'json',
// 返回json数据
return json($data,http状态码);
return json($data)->code(201)->header(['Content-Type' => 'application/json']);
// 输出 Json 格式
$data = ['status' => 1000, 'msg' => '添加成功'];
// 方式 1
return json($data, 201, ['Content-type' => 'application/json']);
// 方式 2
return json($data)->code(201)->header(['Content-Type'=>'application/json']);
///////////////////////////////////////////////////////////////////////////////////////////
// 可以使用redirect助手函数进行重定向
// redirect('地址或方法名', 数组参数);
// 重定向
return redirect(url('index/index/req2', ['id'=>1]));
10.视图
///////////////////////////////////////////////////////////////////////////////////////////
// 视图的组成
// 此处所说的视图就是MVC中所说的V层,视图层也要展示层。
// thinkphp中视图层是由HTML模板文件组成的。
///////////////////////////////////////////////////////////////////////////////////////////
// 模板的定义
// 为了对模板文件更加有效的管理,ThinkPHP对模板文件进行目录划分,
// 默认的模板文件定义规则是:视图目录(view)/控制器名(小写)/方法名(小写)
// + 模板后缀(框架的默认视图文件后缀是.html)
// 实例:
// application/index/controller/Demo.php
// application/index/view/index/index.html
////////////////////////////////////////////////////////////////////////////////////////
// 模板渲染和赋值
// 在控制器中使用
// 渲染 view 函数
// 赋值 局部 compact() 全局 think\facade\View::share();
// 方法1:
return $this->fetch('[模板文件]'[,'模板变量(数组)']);
// 方法2:
return view('[模板文件]'[,'模板变量(数组)']); # 辅助函数
// 针对于自定义路由
return view('index@index/index');
// 模板赋值
// 方法1:了解
$this->assign('name','ThinkPHP');
// 方法2:推荐写法
// 以关联数组的方式在渲染模板方法第二个参数填写[推荐写法]
return view('index@index/index',compact('aa','arr'));
// 全局赋值
use think\facade\View;
// 赋值全局模板变量
View::share('name','value');
// 或者批量赋值
View::share(['name1'=>'value','name2'=>'value2']);
////////////////////////////////////////////////////////////////////////////////////////
// 控制器中指定渲染的模板文件
// 实例
$aa = '我就是变量';
$arr = ['id'=>1, 'name'=>'张三'];
// 模板赋值
// $this->assign('aa', $aa); # 了解
// return view('index@index/index', ['aa'=>$aa, 'arr'=>$arr]);
// 推荐
return view('index@index/index', compact('aa','arr', 'code'));
////////////////////////////////////////////////////////////////////////////////////////
// 全局赋值
// 实例
use think\facade\View;
View::share('webname', '网站的名称');
////////////////////////////////////////////////////////////////////////////////////////
// 使用函数
// 需要对模板输出使用函数进行过滤或其它处理的时候,就可以使用一下函数来解决。
{$password|md5}
// 当然也可以写成如下的写法,推荐
{:md5($password)}
// 注:不但用php系统提供函数,还可以用tp提供的函数,
// 还可以用户在tp规定的文件中定义的写的函数
{$code|md5}
{:md5($code)}
////////////////////////////////////////////////////////////////////////////////////////
// 原样输出
// 因thinkphp5的标签语法和js的一致,所以有的时候,可能会使用到它。
{literal}
Hello,{$name}!
{/literal}
// 上面的 {$name} 标签被 literal 标签包含,因此并不会被模板引擎解析,
// 而是保持原样输出。
<script>
<!-- 原样输出 -->
{literal}
let json = {'name':'{$code}'}
{/literal}
</script>
////////////////////////////////////////////////////////////////////////////////////////
// 循环标签【重点】
// foreach 【推荐写法】
{foreach $list as $key=>$vo }
{$vo.id}:{$vo.name}
{/foreach}
// volist
{volist name="list" id="vo"}
{$vo.id}:{$vo.name}<br/>
{/volist}
////////////////////////////////////////////////////////////////////////////////////////
// 实例
// php文件
$data = [
['id' => 1, 'name' => '张三'],
['id' => 2, 'name' => '李四'],
['id' => 3, 'name' => '王五'],
['id' => 4, 'name' => '赵六'],
];
$age = 10;
return view('index@tt/index', compact('data','age'));
// html 文件
{volist name="data" id="vo" }
<li>{$vo.id}----{$vo.name}</li>
{/volist}
{foreach $data as $val}
<li>{$val.id}----{$val.name}</li>
{/foreach}
////////////////////////////////////////////////////////////////////////////////////////
// 条件判断
{if ( $name == 1) OR ( $name > 100) } value1
{elseif $name == 2 /} value2
{else /} value3
{/if}
////////////////////////////////////////////////////////////////////////////////////////
// 实例
// php文件
$data = [
['id' => 1, 'name' => '张三'],
['id' => 2, 'name' => '李四'],
['id' => 3, 'name' => '王五'],
['id' => 4, 'name' => '赵六'],
];
$age = 10;
return view('index@tt/index', compact('data','age'));
// html 文件
{if $age < 10 } 儿童
{elseif $age < 30 /} 青年
{else /} 老年
{/if}
////////////////////////////////////////////////////////////////////////////////////////
// 模板继承
// 模板继承其实并不难理解,就好比类的继承一样,
// 模板也可以定义一个基础模板(或者是布局),并且其中定义相关的区块(block),
// 然后继承(extend)该基础模板的子模板中就可以对基础模板中定义的区块进行重载。
// 定义一个基础模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>后台网站名称</title>
{block name="css"}{/block}
</head>
<body>
<h3>大家好</h3>
{block name="content"}{/block}
{block name="js"}js{/block}
</body>
</html>
// 在子模板(其实是当前操作的入口模板)中使用继承
<!--继承父模板-->
{extend name="common/base" /}
<!--实现占位-->
{block name="css"}{/block}
{block name="content"}
<div>
<p>
你好世界
</p>
</div>
{/block}
{block name="js"}
<!--继承父占位中的内容-->
{__block__}
{/block}
11.数据库操作
///////////////////////////////////////////////////////////////////////////////////////////
// 连接数据库
// 在应用配置目录或者模块配置目录下面的config/database.php中配置下面的数据库参数
// 注:配置好的,一定要检查mysql服务是否开启,同时也要检查pdo是否打开。
// 同时还是创建好对应的数据库和连接数据库的用户名和密码并确保
// 他们可以连接上你们的mysql服务器。
'type' => 'mysql',
// 服务器地址
'hostname' => '127.0.0.1',
// 数据库名
'database' => 'tp5',
// 用户名
'username' => 'root',
// 密码
password' => '123456',
// 端口
'hostport' => '3306',
// 数据库表前缀
'prefix' => 'tp_',
///////////////////////////////////////////////////////////////////////////////////////////
// 执行原生sql语句
// Db类支持原生SQL查询操作
// 查询
Db::query("select * from think_user where id=? AND status=?", [8, 1]);
// 添加、更新与删除
Db::execute("update think_user set name=:name where status=:status", ['name' => 'thinkphp', 'status' => 1]);
////////////////////////////////////////////////////////////////////////////////////////
// 实例
// 读取配置文件中的配置
echo config('database.prefix');
$sql = "select * from tp_articles where id=?";
// 如果一定要写原生 sql,推荐写此关联数组占位
$sql = "select * from tp_articles where id=:id";
$ret = WuDb::query($sql, ['id' => 103]);
dump($ret);
// 添加
$sql = "insert into tp_articles(title, desn, body) values(:title, :desn, :body)";
$ret = WuDb::execute($sql, ['title' => '我是标题', 'desn' => '我是描述', 'body' => 'afaeqerqr']);
dump($ret);
// 修改
$sql = "update tp_articles set title=:title where id=:id";
$ret = WuDb::execute($sql, ['title'=>'我是修改的', 'id'=>218]);
dump($ret);
// 删除
$sql = "delete from tp_articles where id=:id";
$ret = WuDb::execute($sql, ['id'=>219]);
dump($ret);
////////////////////////////////////////////////////////////////////////////////////////
// 添加数据Db
// 添加一条数据
$data = ['foo' => 'bar', 'bar' => 'foo'];
Db::name('user')->insert($data);
Db::name('user')->data($data)->insert();
db('user')->data($data)->insert();
// 添加数据后如果需要返回新增数据的自增主键
$userId = Db::name('user')->insertGetId($data);
// 添加多条数据
$data = [
['foo' => 'bar', 'bar' => 'foo'],
['foo' => 'bar1', 'bar' => 'foo1'],
['foo' => 'bar2', 'bar' => 'foo2']
];
Db::name('user')->insertAll($data);
db('user')->insertAll($data);
Db::name('user')->data($data)->insertAll();
////////////////////////////////////////////////////////////////////////////////////////
// 实例1
$data = ['title' => '我是标题11111', 'desn' => '我是描述', 'body' => 'aaaaaa'];
// 添加一条数据
// 返回影响的行数
// table 写全表名称
$ret = Db::table('tp_articles')->insert($data);
// name 可以不写表前缀
$ret = Db::name('articles')->insert($data);
// 推荐写法,不需要表前缀
$ret = db('articles')->insert($data);
dump($ret);
// 返回插入成功后的主键 ID
$ret = db("articles")->insertGetId($data);
dump($ret);
////////////////////////////////////////////////////////////////////////////////////////
// 实例2
// 添加多条
$data = [
['title' => '我是标题11111', 'desn' => '我是描述1', 'body' => 'aaaaaa'],
['title' => '我是标题2222', 'desn' => '我是描述2', 'body' => 'bbbbb'],
['title' => '我是标题3333', 'desn' => '我是描述3', 'body' => 'cccccc']
];
$ret = db("articles")->insertAll($data);
dump($ret);
////////////////////////////////////////////////////////////////////////////////////////
// 更新数据
// 更新数据一定要写条件
db('user')->where('id', 1)->update(['name' => 'thinkphp']);
db('user')->where('id', 1)->data(['name' => 'thinkphp'])->update();
Db::name('user')->update(['name' => 'thinkphp','id'=>1]);
// 5.1.7之后还支持了Db::raw写法
Db::name('user')
->where('id', 1)
->update([
'name' => Db::raw('UPPER(name)'),
'score' => Db::raw('score-3'),
'read_time' => Db::raw('read_time+1')
]);
////////////////////////////////////////////////////////////////////////////////////////
// 实例
// 更新数据
$data = ['title' => '我是标题11111', 'desn' => '我是描述1', 'body' => 'aaaaaa'];
$ret = db('articles')->where('id', '=', 211)->update($data);
$ret = db("articles")->where('id', 211)->update($data);
$data = ['id'=>210, 'title' => '我是标题11111', 'desn' => '我是描述1', 'body' => 'aaaaaa'];
$ret = db("articles")->update($data);
$dump($ret);
// 5.1.7 之后还支持了 Db::raw 写法
$ret = db('article')->where('id', 210)->update([
'click' => Db::raw('click+1')
]);
dump($ret);
////////////////////////////////////////////////////////////////////////////////////////
// 删除数据
// 根据主键删除
Db::table('think_user')->delete(1);
Db::table('think_user')->delete([1,2,3]);
// 条件删除
Db::table('think_user')->where('id',1)->delete();
Db::table('think_user')->where('id','<',10)->delete();
// 无条件删除所有数据 小心去用
Db::name('user')->delete(true);
// 软删除数据 使用delete_time字段标记删除 逻辑删除
// 软删除,必须要表中要delete_time字段
Db::name('user')
->where('id', 1)
->useSoftDelete('delete_time',time())
->delete();
////////////////////////////////////////////////////////////////////////////////////////
// 实例
$ret = db("articles")->delete(226);
$ret = db("articles")->delete([224, 225]);
$ret = db("articles")->where('id', 101)->delete();
$ret = db("articles")->where('id', 102)->useSoftDelete('delete_time', time())->delete();
dump($ret);
////////////////////////////////////////////////////////////////////////////////////////
// 查询数据
// 查询一条数据
db('user')->find(主键ID);
Db::name('user')->where('id',1)->find();
// 如果希望在没有找到数据后抛出异常可以使用
Db::name('user')->where('id',1)->findOrFail();
// 查询多条记录
Db::name('user')->where('status',1)->select();
// 如果希望在没有找到数据后抛出异常可以使用
Db::name('user')->where('status',1)->selectOrFail();
// 查询某个字段的值可以用
Db::name('user')->where('id',1)->value('name');
// 查询某一列的值可以用
Db::name('user')->where('id',1)->column('name');
// 排序并获取指定记录条数
Db::name('user')->order('id', 'desc')->limit(0,10)->select();
// 聚合查询
Db::name('user')->count();
Db::name('user')->max('score');
Db::name('user')->where('score', '>', 0)->min('score');
Db::name('user')->avg('score');
Db::name('user')->where('id',10)->sum('score');
// 批量(字段)查询
$map = [
['name', 'like', 'thinkphp%'],
['title', 'like', '%thinkphp'],
['id', '>', 0],
];
Db::table('think_user')
->where([ $map ])
->where('status',1)
->select();
SELECT * FROM `think_user` WHERE ( `name` LIKE 'thinkphp%' AND `title` LIKE '%thinkphp' AND `id` > 0 ) AND `status` = '1'
// 闭包查询
$name = 'thinkphp';
$id = 10;
Db::table('think_user')->where(function ($query) use($name, $id) {
$query->where('name', $name)->whereOr('id', '>', $id);
// 获取器 5.1.20之后才有
Db::name('user')->withAttr('name', function($value, $data) {
return strtolower($value);
})->select();
// 上面的代码,查询的数据集数据中的name字段的值会统一进行小写转换
////////////////////////////////////////////////////////////////////////////////////////
// 实例
// 查询数据
$ret = db('articles')->find(223);
$ret = db('articles')->where('id', 223)->find();
// id 大于 100,click 大于 100
$ret = db('articles')->where('id', '>', 100)->where('click', '>', 100)->select();
// 没有查询分组
$where = [
['id', '>', 100],
['click', '>', 100]
];
ret = db('articles')->where($where)->select();
$where = [
'id' => ['>', 100],
'click' => ['>', 100]
];
$obj = new Where($where);
$ret = db('articles')->where(new Where($where))->select();
// 查询分组
$ret = db('articles')->where(function (Query $query){
$query->where('id', '>', 100)->where('click', '>', 100);
})->whereOr(function (Query $query){
$query->where('title', 'like', 'a%');
})->select();
// 此用法一般用于 接口
$ret = db('articles')->where('id', 985)->findOrFail();
$ret = db('articles')->where('id', '>', 500)->selectOrFail();
// 排序和分页
$ret = db('articles')->order('id', 'desc')->limit(0,2)->select();
//获取指定的字段的值
$ret = db('articles')->where('id', 210)->value('title');
//获取指定的列
$ret = db('articles')->column('title');
$ret = db('articles')->column('title', 'id');
//获取器
$ret = db('articles')->withAttr('title', function($value, $data) {
return '世界您好---'.$value;
})->where('id', '>', 200)->select();
dump($ret);
12.模型操作
///////////////////////////////////////////////////////////////////////////////////////////
// 模型定义与模型设置
php think make:model 模块名/模型名(首字母大写)
// 非必须
protected $pk = 'uid'; # 设置主键名称
protected $table = 'think_user'; #设置当前模型对应的完整数据表名称
////////////////////////////////////////////////////////////////////////////////////////
// 实例
// 文件 application/common/model/Articles.php
// 设置主键 ID
protected $pk = 'id';
// 设置表名
protected $table = 'tp_articles';
// 文件 application/index/controller/Wudi.php
// 实例化
// 方法 1
$model = new Articles();
// 方法 2,推荐
$model = model('Articles');
////////////////////////////////////////////////////////////////////////////////////////
// 添加一条数据
// 方法1
$user = new User;
$user->name = 'thinkphp';
$user->email = 'thinkphp@qq.com';
$user->save();
// 方法2
$user = new User;
$user->save([
'name' => 'thinkphp',
'email' => 'thinkphp@qq.com'
]);
// 过滤post数组中的非数据表字段数据
$user->allowField(true)->save($_POST);
$user->allowField([要插入的字段,要插入的字段])->save($_POST);
// 方法3
$user = User::create([
'name' => 'thinkphp',
'email' => 'thinkphp@qq.com'
]);
echo $user->name;
////////////////////////////////////////////////////////////////////////////////////////
// 添加多条记录
$user = new User;
$list = [
['name'=>'thinkphp','email'=>'thinkphp@qq.com'],
['name'=>'onethink','email'=>'onethink@qq.com']
];
$user->saveAll($list);
////////////////////////////////////////////////////////////////////////////////////////
// 实例
$data = $request->post();
// 添加方案2
$artModel = new Articles();
$ret = $artModel->allowField(true)->save($data);
$ret = $artModel->allowField(['title', 'body'])->save($data);
// 添加方案1,推荐
$ret = Articles::create($data);
dump($ret);
////////////////////////////////////////////////////////////////////////////////////////
// 更新数据
// 方法1
$user = User::get(1); find
$user->name = 'thinkphp';
$user->email = 'thinkphp@qq.com';
$user->save();
// 方法2
$user = new User;
// save方法第二个参数为更新条件
$user->save([
'name' => 'thinkphp',
'email' => 'thinkphp@qq.com'
],['id' => 1]);
$user = new User;
// 过滤post数组中的非数据表字段数据
$user->allowField(true)->save($_POST,['id' => 1]);
// 方法3
User::where('id', 1)->update(['name' => 'thinkphp']);
////////////////////////////////////////////////////////////////////////////////////////
// 实例
$data = ['title'=>'我是修改模型'];
$ret = Articles::where('id', 127)->update($data);
dump($ret);
////////////////////////////////////////////////////////////////////////////////////////
// 删除数据
// 方法1
$user = User::get(1);
$user->delete();
// 方法2
User::destroy(1);
User::destroy([1,2,3]);
////////////////////////////////////////////////////////////////////////////////////////
// 实例
$model = Articles::find(127);
$ret = $model->delete();
// 静态方法,推荐
$ret = Articles::destroy(215);
$ret = Articles::destroy([1,2,3,4,5]);
dump($ret);
////////////////////////////////////////////////////////////////////////////////////////
// 软删除
// 在实际项目中,对数据频繁使用删除操作会导致性能问题,
// 软删除的作用就是把数据加上删除标记,而不是真正的删除,
// 同时也便于需要的时候进行数据的恢复。
// 引入软删除的操作方法
// 文件 application/common/model/Articles.php
use SoftDelete;
//删除的字段名
protected $deleteTime = 'delete_time';
// 文件 application/index/controller/Wudi.php
// 静态方法
$ret = Articles::destroy(215);
// 强制真删除
$ret = Articles::destroy(209, true);
// 软删除的将不会被查询出来
$ret = Articles::select();
$ret = Articles::withTrashed()->select();
$ret = Articles::onlyTrashed()->find(214);
$ret->restore();
dump($ret);
////////////////////////////////////////////////////////////////////////////////////////
// 查询单条记录
$user = User::where('name', 'thinkphp')->find();
// 查询多条记录
$list = User::where('status', 1)->limit(3)->order('id', 'asc')->select();
// 获取某个字段或者某个列的值
// 获取某个用户的积分
User::where('id',10)->value('score');
// 获取某个列的所有值
User::where('status',1)->column('name');
// 条件分组 where () or ()
$ret = Articles::where(function (Query $query){
print_r(func_get_args());
$query->where('id','>',200);
})->whereOr(function (Query $query){
$query->where('click','>=',101);
})->select();
// 动态查询
// 根据name字段查询用户
$user = User::getByName('thinkphp');
////////////////////////////////////////////////////////////////////////////////////////
// 实例
// 模型的查询 get 直接查询,不可以带 where 条件,find 两者都可以
$ret = Articles::get(192);
$ret = Articles::find(192);
$ret = Articles::where('id', 192)->find();
// 条件分组 where () or ()
$ret = Articles::where(function (Query $query) {
print_r(func_get_args());
$query->where('id', '>', 200);
})->whereOr(function(Query $query) {
$query->where('click', '>=', 101);
})->select();
// 查询 title 字段为 "我是张三" 的记录
$ret = Articles::where('title', '我是张三')->select();
// 动态查询 getBy固定字段名,首字母大写,遇到下划线,下划线的后的首字母大写
// 例如: title_article getByTitelArticle
$ret = Articles::getByTitle('我是张三'); //调用了__callStatic
dump($ret);
////////////////////////////////////////////////////////////////////////////////////////
// 获取器
// 获取器的作用是对模型实例的(原始)数据做出自动处理。
// 文件 application/common/model/Articles.php
// 获取器 get 字段名Attr 如果有下划线,下划线的后首字母大写
public function getCreateTimeAttr($value)
{
return date('Y年m月d日 H时i分s秒', strtotime($value));
}
13.数据分页
///////////////////////////////////////////////////////////////////////////////////////////
// 一般在列表页数据展示时,如果数据太多,需要进行分页展示。
// ThinkPHP5.1内置了分页实现,要给数据添加分页输出功能变得非常简单,
// 可以直接在Db类查询的时候调用paginate方法
$list = db('user')->paginate(10);
return view('index@index/user',compact('$list'));
$list = User::paginate(10)
return view('index@index/user',compact('$list'));
// 模板文件中分页输出代码如下
<div>
<ul>
{volist name='list' id='user'}
<li> {$user.nickname}</li>
{/volist}
</ul>
</div>
{$list|raw}
////////////////////////////////////////////////////////////////////////////////////////
// 实例
// 分页
// 文件 application/index/controller/Article.php
$data = Articles::paginate(10);
return view('index@article/index', compact('data'));
// 文件 applicaiton/index/view/article/index.html
{foreach $data as $item}
<tr>
<td>{$item.id}</td>
<td>{$item.title}</td>
<td>
<div class="btn-group">
<a href="#" class="btn btn-xs btn-primary">修改</a>
<a href="#" class="btn btn-xs btn-danger">删除</a>
</div>
</td>
</tr>
{/foreach}
14.表单验证
///////////////////////////////////////////////////////////////////////////////////////////
// 表单验证是为了防止访问者跳过客户端验证(js验证)而造成的系统安全问题,
// 一但非法用户绕过客户端验证而服务器端没有加以验证,这样就是很不安全了,
// 所以项目必须要进行服务器端表单验证。
// ThinkPHP5.1推荐使用验证器进行数据验证
// (也支持使用\think\Validate类进行独立验证)
// 内置规则:
// https://www.kancloud.cn/manual/thinkphp5_1/354107
////////////////////////////////////////////////////////////////////////////////////////
// 独立验证
$validate = Validate::make([
'name' => 'require|max:25',
'email' => 'email'
],[
'name.require' => '名称必须填写',
'name.max' => '名称最多只能是25字',
'email.email' => '邮箱不合法'
]);
$data = [
'name' => 'thinkphp',
'email' => 'thinkphp@qq.com'
];
if (!$validate->check($data)) {
dump($validate->getError());
}
// 自定义验证规则
Validate::extend('checkName', function ($value, $rule) {
return $rule == $value ? true : '名称错误';
});
////////////////////////////////////////////////////////////////////////////////////////
// 实例
// 独立验证规则 use think\facade\Validate
// 自定义验证规则
Validate::extend('checkTitle', function ($value, $rule) {
dump(func_get_args());
return strstr($value, $rule) ? '不成功' : true;
});
// 验证
$validate = Validate::make([
'title' => 'require|min:2|checkTitle:李四',
'desn' => 'require',
],[
'title.require' => '标题不能为空',
'title.min' => '标题最少不能少于2个字',
'desn.require' => '描述不能为空',
]);
// 判断
if (!$validate->check($request->post()))
{
return $this->error($validate->getError());
}
////////////////////////////////////////////////////////////////////////////////////////
// 验证器
// thinkphp5.1之后推荐使用的方式,验证器,就是一个独立的文件,
// 此文件就干一件事件,验证。
// 创建验证器
php think make:validate 模块名/验证器名(首字母大写)
// 验证器
namespace app\index\validate;
use think\Validate;
class User extends Validate
{
protected $rule = [
'name' => 'require|max:25',
'age' => 'number|between:1,120',
'email' => 'email',
];
protected $message = [
'name.require' => '名称必须',
'name.max' => '名称最多不能超过25个字符',
'age.number' => '年龄必须是数字',
'age.between' => '年龄只能在1-120之间',
'email' => '邮箱格式错误',
];
}
// 控制器
$ret = $this->validate($request->post(),User::class);
if (true !== $ret){
dump($ret);
}
////////////////////////////////////////////////////////////////////////////////////////
// 实例
// 验证器
// 文件 application/index/validate/ArticleValidate.php
protected $rule = [
'title' => 'require|checkName:aa|token',
];
protected $message = [
'title.require' => '标题不能为空',
];
// 控制器
// 文件 application/index/controller/Article.php
// 验证器
// 第1种 了解即可
$validate = new ArticleValidate();
// 验证
if (!$validate->check($request->post()))
{
return $this->error($validate->getError());
}
// 第2种 控制器中有 Validate 方法
$ret = $this->validate($request->post(), 'app\index\validate\ArticleValidate');
$ret = $this->validate($request->post(), ArticleValidate::class);
if (true !== $ret)
{
return $this->error($ret);
}
////////////////////////////////////////////////////////////////////////////////////////
// csrf验证
// 验证器
// 文件 application/index/validate/ArticleValidate.php
protected $rule = [
'title' => 'require|checkName:aa|token',
];
// 文件 application/index/view/article/add.html
{:token()}
15.验证码
///////////////////////////////////////////////////////////////////////////////////////////
// 验证码
// https://www.kancloud.cn/manual/thinkphp5_1/354122
// tp5框架中默认没有自带验证码功能,需要我们自己去引入安装
// 官方提供的tp官方验证码类
composer require topthink/think-captcha
// 模板中引用
<div>{:captcha_img()}</div>
或者
<div><img src="{:captcha_src()}" alt="captcha" /></div>
// 验证
$this->validate($data,[
'code'=>'require|captcha'
]);
或者
if(!captcha_check($captcha)){
// 验证失败
};
////////////////////////////////////////////////////////////////////////////////////////
// 实例
// 命令行输入命令
composer require topthink/think-captcha
// 验证器
// 文件 application/index/validate/LoginValidate.php
protected $rule = [
'code' => 'require|captcha|token',
];
protected $message = [
'code.captcha' => '你想干嘛,验证码都不录入',
];
// 控制器
// 1.验证器去验证验证码 推荐
// 文件 application/index/controller/Login.php
$ret = $this->validate($request->post(), LoginValidate::class);
if (true !== $ret)
{
return $this->error($ret);
}
// 2.独立去验证验证码
// 文件 application/index/controller/Login.php
$code = $request->post('code');
if (!captcha_check($code))
{
return $this->error('验证不正确');
}
// html 模板
// 文件 application/index/view/login/index.html
<div class="col-sm-5">
<img src="{:captcha_src()}" id="vcode" alt="" />
</div>
<script>
$('#vcode').click(function(){
let src = $(this).attr('src') + '?vt=' + Math.random();
$(this).attr('src', src);
});
</script>
16.cookie和session处理
///////////////////////////////////////////////////////////////////////////////////////////
// cookie操作
// ThinkPHP采用think\facade\Cookie类提供Cookie支持。think\Cookie
// 配置文件位于 config/cookie.php中
// 设置Cookie 有效期为 3600秒
Cookie::set('name','value',3600);
cookie('name', 'value', 3600);
// 判断是否存在
Cookie::has('name');
cookie('?name')
// 获取
Cookie::get('name');
cookie('name');
//删除
Cookie::delete('name');
cookie('name', null);
///////////////////////////////////////////////////////////////////////////////////////////
// 实例
// 设置
cookie('name', '张三', 300);
// 判断是否存在
dump(cookie('?name'));
// 获取
dump(cookie('name'));
// 删除
cookie('name', null);
dump(cookie('?name'))
// 清除所有,必须有前缀
Cookie::clear('aa_');
cookie(null, 'aa_');
////////////////////////////////////////////////////////////////////////////////////////
// session操作
// 可以直接使用think\facade\Session类操作Session
// 配置文件位于config/session.php文件中
// 设置
Session::set('name','thinkphp');
session('name', 'thinkphp');
// 闪存
Session::flash('name','value');
// 判断是否存在
Session::has('name');
session('?name');
// 取值
Session::get('name');
session('name');
// 删除
Session::delete('name');
session('name', null);
// 清空
Session::clear();
session(null);
////////////////////////////////////////////////////////////////////////////////////////
// 实例
// 设置
session('name', '张三');
session('age', '20');
// 个人在项目中定义 session 的习惯
session('admin.user', '张三');
session('index.user', '李四');
// 判断是否存在
dump(session('?name'));
// 获取
dump(session('name'));
// 删除指定的 session
session('name', null);
dump(session('?name'));
// 清空全部
session(null);
dump(session('age'))
// 获取全部
dump(session(''));
////////////////////////////////////////////////////////////////////////////////////////
// 闪存
// 定义好,在下一次HTTP请求中获取到,第2没有了
Session::flash('name','value');
////////////////////////////////////////////////////////////////////////////////////////
// 实例
// 跳转并写下闪存信息
// cookie
return redirect(url('cs'))->with('success','登录成功');
// session
// \think\facade\Session::flash('success', '登录成功');
dump(session('success'));
17.中间件
///////////////////////////////////////////////////////////////////////////////////////////
// 中间件主要用于拦截或过滤应用的HTTP请求,并进行必要的业务处理。
// 传统式用户过滤
// 通过继承基类来达到权限的判断
// 文件 application/index/controller/Base.php
class Base extends Controller
{
// tp 框架中构造方法
public function initialize()
{
// 相关的权限判断
if (!session('?login'))
{
// return redirect('login')->with(['message'=>'请登录']);
// return $this->error('请登录', url('login'));
}
// 假如有业务,大家后台都是要需要的,就可以在此写了
//view::share('name', '你好世界');
//echo '成功后就可以进行不处理<hr/>';
}
}
// 文件 application/index/controller/User.php
class User extends Base
{
public function index()
{
echo "后台管理";
}
}
////////////////////////////////////////////////////////////////////////////////////////
// 定义中间件
// https://www.kancloud.cn/manual/thinkphp5_1/564279
// 这个指令会 application/http/middleware目录下面生成一个中间件文件。
php think make:middleware 中间件的名称
////////////////////////////////////////////////////////////////////////////////////////
// 实例
php think make:middleware CheckLogin
// 文件 application/index/controller/http/middleware/CheckLogin.php
namespace app\http\middleware;
class CheckLogin
{
public function handle($request, \Closure $next, $args)
{
echo $args;
echo "php 您好22222222222222<hr/>";
return $next($request);
}
}
////////////////////////////////////////////////////////////////////////////////////////
// 控制器注册 pathinfo
protected $middleware = [
// 中间件的类名称
'CheckLogin'
];
////////////////////////////////////////////////////////////////////////////////////////
// 自定义路由 middleware
Route::group(['middleware'=>['CheckLogin:guest']], function (){
Route::get('login', '@index/login/index')->name('login');
});
////////////////////////////////////////////////////////////////////////////////////////
// 配置文件 middleware.php
// 此文件可以放在模块下,就是对此模块注册此中间件,在application下面,
// 就是全局中间件,说白了,就是所有的模块讲都有此中间件。
// 文件 application/index/middleware.php 针对 index 模块的中间件
// 文件 application/middleware.php 针对全局中间件
return [
#\app\http\middleware\CheckLogin::class,
[\app\http\middleware\CheckLogin::class, 'admin'],
];
////////////////////////////////////////////////////////////////////////////////////////
// 中间件参值
// 文件 application/index/controller/http/middleware/CheckLogin.php
namespace app\http\middleware;
class CheckLogin
{
public function handle($request, \Closure $next, $args)
{
// 中间件的参数值获取
echo $args;
echo "php 您好22222222222222<hr/>";
return $next($request);
}
}
// 文件 application/index/middleware.php
return [
#\app\http\middleware\CheckLogin::class,
[\app\http\middleware\CheckLogin::class, 'admin'],
];
// 文件 application/index/controller/Login.php
protected $middleware = [
// 中间件的类名称
'CheckLogin',
// 中间件传值
'CheckLogin:user'
];
posted on 2020-03-14 14:02 herisson_pan 阅读(43) 评论(0) 收藏 举报
浙公网安备 33010602011771号