Thinkphp6(tp6) 更新笔记

composer create-project topthink/think tp
cd tp
composer require topthink/think-multi-app
composer require topthink/think-view    //如果你需要使用think-template模板引擎,只需要安装think-view模板引擎驱动。

composer require topthink/think-captcha   //验证码

php think make:model Profile

插入:
Db::table('user')->insert(["username"=>"xx","passwd"=>2,"email"=>222]);
查询:
Db::table('user')->select();   //->find();
改:
Db::name("user")->where('id',1)->update([]);
Db::name("user")->delete(1);
Db::name("user")->where('id',1)->delete();
halt($u); //类似于dd;
---------------------------------
通过模型:
新建一个模型文件并从think\Model下继承Model;
protected $name = 'user'; //指定数据表名;
使用时引入:use app\common\model\User;
使用:$user = new User;        $user->username = "xxx";   //   $user->save();

更新:
$user = User::find(1);
$user->username = 'xxxx'; //save();

$user = User::find(1);
$user->delete();

$user::select([4,5]);

视图:
use think\facade\view;

return View::fetch('demo/index',["id"=>"xx"]) // 默认为index/view/demo/index.html;
View('demo/index',['user'=>'xiaoming']);
加载配置文件,额外的
\think\facade\Config::load('extra/config', 'extra');
获取变量的值:
Env::get('database.username', 'root'); // 获取环境变量 如果不存在则使用默认值root
Env::get('database.username');
Env::get('database.password');
Env::get('PATHINFO_PATH');

use think\facade\Config;
Config::get('database.default.host');
判断是否存在某个设置参数:
Config::has('route.route_rule_merge');
Config::set(['name1' => 'value1', 'name2' => 'value2'], 'config');
http://serverName/index.php/shop
http://serverName/index.php/admin
/控制器/操作/参数/值…
也就是说 pathinfo 地址的第一个参数就表示当前的应用名, 后面才是该应用的路由或者控制器/操作。

如果需要获取当前的应用名, 可以使用 app('http')->getName();
root_path()   根目录
base_path()  基础目录
app_path()  app目录
runtime_path()
config_path()
nginx:
location / { // …..省略部分代码
  if (!-e $request_filename) {
    rewrite ^(.*)$ /index.php?s=/$1 last;
  }
}


Route::get('user/:id','index/Index/hello')->model('\app\index\model\User');//路由绑定模型

<?php
namespace app\index\controller;
use app\index\model\User;
class Index
{
public function hello(User $user)
{
    return 'Hello,'.$user->name;
}
}

Facade功能可以让类无需实例化而直接进行静态方式调用;
所以你无需进行实例化就可以很方便的进行方法调用, 例如:
use think\facade\Cache;
Cache::set('name','value');
echo Cache::get('name');

php think make:middleware Check

中间件的入口执行方法必须是 handle 方法, 而且第一个参数是 Request 对象, 第二个参数是一个闭包。中间件 handle 方法的返回值必须是一个 Response 对象。
$http = (new App())->setEnvName('develop')->http;    //加载 .env.develop 配置文件,这样可以区分开发和生产环境;

use think\facade\Config;
Config::get('app.app_name');   读取配置文件变量;

路由的作用远非URL规范这么简单, 还可以实现验证、 权限、 参数绑定及响应设置等功能;
模型类通常完成实际的业务逻辑和数据封装, 并返回和格式无关的数据。

中间件主要用于拦截或过滤应用的 HTTP 请求, 并进行必要的业务处理。
php think version   //控制台应用

多入口: http://serverName/index.php/think     会访问 /route/app.php
Route::get('think', function () {
return 'hello,ThinkPHP!';
});  中的路由定义;

$response = $http->path('path/to/app')->run(); //指定应用路径;

-----------------------------------
使用admin应用,增加入口文件时引入 name admin,这样使用admin应用;
//$response = $http->run();
$response = $http->name('admin')->run();
获取当前应用名: app('http')->getName();

URL:
http://serverName/index.php/控制器/操作/参数/值…

多应用:
http://serverName/index.php/应用/控制器/操作/参数/值...

参数兼容方式:
http://serverName/index.php?s=/控制器/操作/[参数名/参数值...

容器类的工作由 think\Container 类完成, 但大多数情况我们只需要通过 app 助手函数或者think\App 类即可容器操作, 如果在服务类中可以直接调用 this->app 进行容器操作。

$app = app();
// 判断对象实例是否存在
isset($app->cache);
// 注册容器对象实例
$app->cache = think\Cache::class;
// 获取容器中的对象实例
$cache = $app->cache;
// 调用配置类
app()->config->get('app_name');
// 调用session类
app()->session->get('user_name');
----------------------------------------------
可以给路由绑定模型对象实例
Route::get('user/:id','index/Index/hello')
->model('\app\index\model\User');
然后在操作方法中自动注入User模型:
use app\index\model\User;
public function hello(User $user)
{
    return 'Hello,'.$user->name;
}
生成一个服务类:
php think make:service FileSystemService
默认生成的服务类会继承系统的 think\Service , 并且自动生成了系统服务类最常用的两个空方法:register 和 boot 方法。
register 方法通常用于注册系统服务, 也就是将服务绑定到容器中;
class FileSystemService extends Service
{
public function register()
{
$this->app->bind('file_system', FileSystem::class);
}
}
门面为容器中的( 动态) 类提供了一个静态调用接口;说的直白一点, Facade功能可以让类无需实例化而直接进行静态方式调用。
生成中间件:
php think make:middleware Check
中间件 handle 方法的返回值必须是一个 Response 对象。
中间件支持定义请求结束前的回调机制, 你只需要在中间件类中添加 end 方法。
1全局中间件->2应用中间件->3路由中间件->4控制器中间件
    1.全局中间件在 app 目录下面 middleware.php 文件中定义;
    2. 应用目录下面增加 middleware.php 文件, 定义方式和全局中间件定义一样, 只是只会在该应用下面生效。
    3. 路由中间件最常用:Route::rule('hello/:name','hello')->middleware(\app\middleware\Auth::class);
        Route::rule('hello/:name','hello')->middleware([\app\middleware\Auth::class, \app\middleware\Check::class]);
分组中间件:
Route::group('hello', function(){
Route::rule('hello/:name','hello');
})->middleware('auth');
------------------------------------
Route::domain('admin', function(){
// 注册域名下的路由规则,所有admin都需要登录
})->middleware('auth');
传参给中间件:Route::rule('hello/:name','hello')->middleware('auth', 'admin');
可以统一传入同一个额外参数 Route::rule('hello/:name','hello')->middleware(['auth', 'check'], 'admin');
或者分开多次调用, 指定不同的参数Route::rule('hello/:name','hello')->middleware('auth', 'admin')->middleware('hello', 'thinkphp');

如可所有的路由均要添加中间件,可以在 config/route.php中配置;
闭包中间件:
Route::group('hello', function(){
Route::rule('hello/:name','hello');
})->middleware(function($request,\Closure $next){
if ($request->param('name') == 'think') {
return redirect('index/think');
}
return $next($request);
});

4.控制器中间件:
   控制器中定义 middleware 属性;
class Index
{
protected $middleware = [
'auth' => ['except' => ['hello'] ],
'check' => ['only' => ['hello'] ],
];
public function index()
{
return 'index';
}

事件本身可以是一个类, 并且可以更好的支持事件订阅者。
事件系统的所有操作都通过 think\facade\Event 类进行静态调用。
// 触发UserLogin事件 用于执行用户登录后的一系列操作
Event::trigger('UserLogin');    
event('UserLogin');    //使用助手函数;

生成事件:事件类可以通过命令行快速生成
php think make:event UserLogin
动态绑定:Event::bind(['UserLogin' => 'app\event\UserLogin']);

你可以在 event 方法中传入一个事件参数
// user是当前登录用户对象实例
event('UserLogin', $user);
如果是定义了事件类, 可以直接传入事件对象实例
// user是当前登录用户对象实例
event(new UserLogin($user));

可以通过命令行快速生成一个事件监听类  php think make:listener UserLogin
你可以手动注册一个事件监听
Event::listen('UserLogin', function($user) {
//
});
或者使用监听类来执行监听
Event::listen('UserLogin', 'app\listener\UserLogin');
// 监听所有的模型事件
Event::listen('model.*', 'app\listener\ModelListen');

绑定事件:在event.php中:
return [
'bind' => [
'UserLogin' => 'app\event\UserLogin',
// 更多事件绑定
],
'listen' => [
'UserLogin' => ['app\listener\UserLogin'],
// 更多事件监听],]

事件订阅:
php think make:subscribe User

Route::rule('路由表达式', '路由地址', '请求类型');
Route::rule('new/:id', 'News/update', 'POST');

Route::rule('new/:id','News/read','GET|POST');
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::get('new/:cate$', 'News/category');  //希望URL进行完全匹配
Route::get('blog/:id','blog/read')->append(['status' => 1, 'app_id' =>5]);   //隐性传值;
Route::rule("new/:id",News/read')->name('new_read');

url('new_read', ['id' => 10]) //生成地址的时候,用name;

Route::get('item-<name><id?>', 'product/detail')->pattern(['name' => '[a-zA-Z]+', 'id' => '\d+']);

Route::get('blog/:id','Blog/read');   //路由到控制器的read操作;
Route::get('blog/:id','\app\index\service\Blog@read'); //路由到类
Route::get('blog/:id','\app\index\service\Blog::read');  //路由到类的静态方法;
Route::redirect('blog/:id', 'http://blog.thinkphp.cn/read/:id', 302);重定向
// 路由到模板文件
Route::view('hello/:name', 'index/hello');
表示该路由会渲染当前应用下面的 view/index/hello.html 模板文件输出。

Route::view('hello/:name', 'index/hello', ['city'=>'shanghai']);  //给模板增加变量;
在闭包中指定响应状态码和内容格式:
Route::get('hello/:name', function () {
response()->data('Hello,ThinkPHP')
->code(200)
->contentType('text/plain');
});
---------------------------------------
Route::get('new/:id', 'News/read')->ext('html')->https();
这些路由参数可以混合使用, 只要有任何一条参数检查不通过, 当前路由就不会生效, 继续检测后面的路由规则
Route::get('new/:id', 'News/read')->option(['ext' => 'html','https' => true]);
-----------------------------------
Route::get('new/:id', 'News/read')->ext('shtml|html');
----------------------------------
// 完整域名检测 只在news.thinkphp.cn访问时路由有效
Route::get('new/:id', 'News/read')->domain('news.thinkphp.cn');
// 子域名检测
Route::get('new/:id', 'News/read')->domain('news');
-------------------------------------
// 必须是JSON请求访问
Route::get('new/:id', 'News/read')->json();
---------------------------
路由规则和分组支持绑定模型数据, 例如:
Route::get('hello/:id', 'index/hello')->model('id', '\app\index\model\User');
会自动给当前路由绑定 id 为 当前路由变量值的 User 模型数据。
默认情况下, 如果没有查询到模型数据, 则会抛出异常, 如果不希望抛出异常, 可以使用
Route::rule('hello/:id', 'index/hello')
->model('id', '\app\index\model\User', false);

Route::rule('hello/:name/:id', 'index/hello')
->model('id&name', '\app\index\model\User'); //模糊查询,id,name;

Route::get('new/:name$', 'News/read')->cache(3600); 表示对当前路由请求缓存 3600 秒, 更多内容可以参考请求缓存一节。

Route::rule('hello/:name','hello')->middleware(\app\middleware\Auth::class);  
Route::group('hello', function(){
Route::rule('hello/:name','hello');
})->middleware(\app\middleware\Auth::class);
资源路由:
Route::resource('blog', 'Blog');
全局miss路由:
Route::miss(function() {
return '404 Not Found!';
});
如果某个路由或者分组需要支持跨域请求, 可以使用:
Route::get('new/:id', 'News/read')
->ext('html')
->allowCrossDomain();

那么必须使用路由标识来生成URL地址 Route::buildUrl('blog_read', ['id' => 5, 'name' => 'thinkphp']);以上方法都会生成下面的URL地址:/index.php/blog/5/name/thinkphp.html
自动生成域名Route::buildUrl('index/blog/read', ['id'=>5])->suffix('shtml')->domain(true);
打印结果 :http://localhost:8080/index.php/index/blog/read.html?id=5

控制器一般不需要任何输出, 直接 return 即可。 并且控制器在 json 请求会自动转换为 json 格式输出。
如果你需要调试并中止执行, 可以使用系统提供的 halt 助手函数。
多级控制器:
文件位置:app/index/controller/user/Blog.php 访问地址可以使用 http://serverName/index.php/user.blog/index
则实现名字空间为:namespace app\index\controller\user;   class Blog   { index方法}
生成控制器:
php think make:controller index@Blog
php think make:controller app\index\controller\Blog
php think make:controller index@Blog --api

请求对象:
当前的请求对象由 think\Request 类负责, 该类不需要单独实例化调用, 通常使用依赖注入即可。 在其它场
合则可以使用 think\facade\Request 静态类操作。
public function index(Request $request)
{
   return $request->param('name');
}
通过facade门面:
Request::param('name');
request()->param('name');    助手函数;

如果使用了多应用模式, 可以通过下面的方法来获取当前应用
app('http')->getName();

可以通过 Request 对象完成全局输入变量的检测、 获取和安全过滤, 支持包括 $_GET 、 $_POST 、$_REQUEST 、 $_SERVER 、 $_SESSION 、 $_COOKIE 、 $_ENV 等系统变量, 以及文件上传信息。
Request::has('id','get');  可以使用 has 方法来检测一个变量参数是否设置,变量检测可以支持所有支持的系统变量, 包括get/post/put/request/cookie/server/session/env/file

// 只获取当前请求的id和name变量
Request::only(['id','name']);

// 排除GET请求的id和name变量
Request::except(['id','name'], 'get');
// 排除POST请求的id和name变量
Request::except(['id','name'], 'post');

变量的类型:
Request::get('id/d');
Request::post('name/s');
Request::post('ids/a');
判断变量是否定义:input('?get.id');  input('?post.name');
input('param.name'); // 获取单个参数
input('param.'); // 获取全部参数

input('get.name','','htmlspecialchars'); // 获取get变量 并用htmlspecialchars函数过滤
input('username','','strip_tags'); // 获取param变量 并用strip_tags函数过滤
input('post.name','','org\Filter::safeHtml'); // 获取post变量 并用org\Filter类的safeHtml方法过滤
获取变量,并按变量修饰符生成指定的类型:d->int,a->array,s->string
input('get.id/d');
input('post.name/s');
input('post.ids/a');
请求类型:
isGet,isPost,isJson,isMobile,isHead
Request::header();
Request::header('user-agent');
$ext = Request::ext();//获取伪静态的扩展名
响应对象:
输出类型 快捷方法 对应Response类
HTML输出 response \think\Response
渲染模板输出 view \think\response\View
JSON输出 json \think\response\Json
JSONP输出 jsonp \think\response\Jsonp
XML输出 xml \think\response\Xml
页面重定向 redirect \think\response\Redirect
附件下载 download \think\response\File
return json($data);   以json返回  json($data)->code(201);
json($data)->code(201)->header([
'Cache-control' => 'no-cache,must-revalidate'
]);
重定向:
return redirect('http://www.thinkphp.cn');
return redirect('/hello')->with('name','thinkphp');
public function hello()
{
  $name = session('name');
  return 'hello,'.$name.'!';
}

if (session('?complete')) 判断session变量是否存在;
return redirect('hello')->with('name', 'thinkphp')->remember();
redirect()->restore(); 返回原来存盘的地址
return download('image.jpg', 'my.jpg'); 访问 download 操作就会下载命名为 my.jpg 的图像文件。下载文件的路径是服务器路径而不是URL路径, 如果要下载的文件不存在, 系统会抛出异常。
return download('image.jpg', 'my')->expire(300); 设置文件下载的有效期

要使用Db类必须使用门面方式( think\facade\Db ) 调用;
Db::name('user')->where('id', 1)->update(['name' => 'thinkphp']);
Db::name('user')->master(true)->find(1);

查:
Db::table('think_user')->where('id', 1)->find();
// table方法必须指定完整的数据表名

Db::table('think_user')->where('id', 1)->findOrEmpty();  //失败后返回空

Db::table('think_user')->where('id', 1)->findOrFail();  //失败后返回异常

Db::table('think_user')->where('status', 1)->select();  //多条;
Db::table('think_user')->where('status', 1)->select()->toArray();   转换
Db::table('think_user')->where('status',1)->selectOrFail();
Db::name('user')->where('id', 1)->find(); //如果设置了前缀,就要使用name了,没有则使用表;
这个很常用,查询返回记录的某个值:比如,查询id为1的记录的姓名:
Db::table('think_user')->where('id', 1)->value('name');
返回数组:名称列:
Db::table('think_user')->where('status',1)->column('name');
数据分批处理:
Db::table('think_user')->chunk(100, function($users) {
foreach ($users as $user) {
//}
});
你可以通过从闭包函数中返回 false 来中止对后续数据集的处理:
Db::table('think_user')->chunk(100, function($users) {
foreach ($users as $user) {
// 处理结果集...
if($user->status==0){
return false;
}
}
});
如果你需要处理大量的数据, 可以使用新版提供的游标查询功能, 该查询方式利用了PHP的生成器特性, 可以大
幅减少大量数据查询的内存开销问题
$cursor = Db::table('user')->where('status', 1)->cursor();
foreach($cursor as $user){
    echo $user['name'];
}

$data = ['foo' => 'bar', 'bar' => 'foo'];
Db::name('user')->save($data);

$data = ['foo' => 'bar', 'bar' => 'foo'];
Db::name('user')->insert($data);

$userId = Db::name('user')->insertGetId($data);   //插入数据并返回主键;
$data = [
['foo' => 'bar', 'bar' => 'foo'],
['foo' => 'bar1', 'bar' => 'foo1'],
['foo' => 'bar2', 'bar' => 'foo2']
];
Db::name('user')->insertAll($data);

// 分批写入 每次最多100条数据
Db::name('user')
->limit(100)
->insertAll($data);

Db::name('user')
->where('id', 1)
->data(['name' => 'thinkphp'])
->update();

如果数据中包含主键, 可以直接使用:Db::name('user')->update(['name' => 'thinkphp','id' => 1]);
如果要更新的数据需要使用 SQL 函数或者其它字段, 可以使用下面的方式:
Db::name('user')->where('id',1)->exp('name','UPPER(name)')->update();

支持使用 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')
]);

// score 字段加 1
Db::table('think_user')->where('id', 1)->inc('score')->update();

Db::table('think_user')->delete([1,2,3]);
Db::table('think_user')->where('id','<',10)->delete();
// 无条件删除所有数据 Db::name('user')->delete(true);
whereBetweenTime   / whereTime

模糊查询:Db::name('user')->where('name', 'like', 'thinkphp%')->select();
Db::name('user')->where('name', 'like', ['%think','php%'],'OR')->select();

Db::name('user')->whereLike('name','thinkphp%')->select();
Db::name('user')->whereNotLike('name','thinkphp%')->select();

Db::name('user')->where('id','between',[1,8])->select();
Db::name('user')->where('id','in',[1,5,8])->select();

Db::name('user')->where('name', null)->where('email','null')->where('name','not null')->select();

Db::name('user')->whereNull('name')->whereNull('email')->whereNotNull('name')->select();

exp 查询的条件不会被当成字符串, 所以后面的查询条件可以使用任何SQL支持的语法, 包括使用函数和字段
名称。Db::name('user')->whereExp('id', 'IN (1,3,8) ')->select();

Db::table('think_user')->where('status',1)->order('create_time')->limit(10)->select();

Db::table('think_user')->where('id',1)->field('id,name,email')->find();

// 传入数组作为查询条件
Db::table('think_user')->where([
['name','=','thinkphp'],
['status','=',1]
])->select();

Db::table('think_user')->whereRaw('type=1 AND status=1')->select();
Db::name('user')->where('status>1')->select();
多表操作:
Db::field('user.name,role.title')->table('think_user user,think_role role')->limit(10)->select();
Db::field('user.name,role.title')->table(['think_user'=>'user','think_role'=>'role'])->limit(10)->select();
别名:Db::table('think_user')->alias('a')->join('think_dept b ','b.user_id= a.id')->select();
Db::table('think_user')->alias(['think_user'=>'user','think_dept'=>'dept'])->join('think_dept','dept.user_id= user.id')->select();
指定字段:Db::table('user')->field('id,title,content')->select();
字段别名:Db::table('user')->field('id,nickname as name')->select();
Db::table('user')->fieldRaw('id,SUM(score)')->select();
Db::table('user')->field(['id','nickname'=>'name'])->select();
Db::table('user')->select();
Db::table('user')->field('*')->select();
Db::table('user')->withoutField('content')->select(); //排除字段
Db::table('user')->withoutField(['user_id','content'])->select();
Db::table('user')->field('title,email,content')->insert($data);
strict 方法用于设置是否严格检查字段名, 用法如下:
// 关闭字段严格检查 Db::name('user')->strict(false)->insert($data);
Db::table('article')->limit(10,25)->select(); //分页查询;

// 查询第一页数据
Db::table('article')->page(1,10)->select();
// 查询第二页数据
Db::table('article')->page(2,10)->select();
自动分页:Db::table('article')->limit(25)->page(3)->select();
排序 : ->order('id', 'desc')
Db::table('user')->where('status', 1)->orderRaw("field(name,'thinkphp','onethink','kancloud')")->limit(5)->select();
GROUP 方法通常用于结合合计函数, 根据一个或多个列对结果集进行分组 。
Db::table('score')->field('username,max(score)')->group('user_id')->having('count(test_time)>3')->select();
(right:右,left:左;)
INNER JOIN: 等同于 JOIN( 默认的JOIN类型) ,如果表中有至少一个匹配, 则返回行
LEFT JOIN: 即使右表中没有匹配, 也从左表返回所有的行
RIGHT JOIN: 即使左表中没有匹配, 也从右表返回所有的行
FULL JOIN: 只要其中一个表中存在匹配, 就返回行
Db::table('think_user')->alias('a')->join(['think_work'=>'w'],'a.id=w.artist_id')->join(['think_card'=>'c'],'a.card_id=c.id')->select();
合并两个结果集:
Db::field('name')->table('think_user_0')->union([
'SELECT name FROM think_user_1',
'SELECT name FROM think_user_2',
])->select()  UNION 内部的 SELECT 语句必须拥有相同数量的列。 列也必须拥有相似的数据类型。 同时, 每条 SELECT 语
句中的列的顺序必须相同。
去重:Db::table('think_user')->distinct(true)->field('user_login')->select(); //去重user_login字段;
Db::name('user')->where('id',1)->lock(true)->find();    //Db::name('user')->where('id',1)->lock('lock in share mode')->find();
缓存:
Db::table('user')->where('id',5)->cache(true)->find();
Db::table('user')->cache(true,60)->find();
// 或者使用下面的方式 是等效的
Db::table('user')->cache(60)->find();
cache方法可以指定缓存标识:Db::table('user')->cache('key',60)->find();
echo Db::table('user')->fetchSql(true)->find(1);   //返回sql语句;
Db::table('user')->force('user')->select();  //对查询强制使用 user 索引, user 必须是数据表实际创建的索引名称。
// 数据不存在的话直接抛出异常
Db::name('blog')
->where('status',1)
->failException()
->select();
// 数据不存在返回空数组 不抛异常
Db::name('blog')
->where('status',1)
->failException(false)
->select();

Db::table('think_user')->count();  Db::table('think_user')->count('id');
Db::table('think_user')->max('score');

// 查询状态为1的用户数据 并且每页显示10条数据
$list = Db::name('user')->where('status',1)->order('id', 'desc')->paginate(10);
// 渲染模板输出
return view('index', ['list' => $list]);

// 查询状态为1的用户数据 并且每页显示10条数据
$list = Db::name('user')->where('status',1)->order('id', 'desc')->paginate(10);
// 获取分页显示
$page = $list->render();
return view('index', ['list' => $list, 'page' => $page]);
分页模板:
<ul class="pagination">
<li><a href="?page=1">&laquo;</a></li>
<li><a href="?page=1">1</a></li>
<li class="active"><span>2</span></li>
<li class="disabled"><span>&raquo;</span></li>
</ul>
----------------------------------
// 查询状态为1的用户数据 并且每页显示10条数据
$list = Db::name('user')->where('status',1)->order('id' ,'desc')->paginate(10);
// 获取总记录数
$count = $list->total();
return view('index', ['list' => $list, 'count' => $count]);
----------------------------------
分页变量:
list_rows 每页数量 page 当前页 path url路径 query url额外参数 fragment url锚点 var_page 分页变量
对于大量数据的分页查询, 系统提供了一个高性能的 paginateX 分页查询方法, 用法和 paginate 分页查询存在一定区别。 如果你要分页查询的数据量在百万级以上, 使用 paginateX 方法会有明显的提升, 尤其是在分页数较大的情况下。 并且由于针对大数据量而设计, 该分页查询只能采用简洁分页模式, 所以没有总数。
$list = Db::name('user')->where('status',1)->paginateX(20, 'id', 'desc');
自定义分页:
然后在 provider.php 定义文件中重新绑定 return [ 'think\Paginator' => 'app\common\Bootstrap' ];
时间比较:
// 大于某个时间
Db::name('user')->whereTime('birthday', '>=', '1970-10-1')->select();
// 小于某个时间
Db::name('user')->whereTime('birthday', '<', '2000-10-1')->select();
// 时间区间查询
Db::name('user')->whereTime('birthday', 'between', ['1970-10-1', '2000-10-1'])->select();
// 不在某个时间区间
Db::name('user')->whereTime('birthday', 'not between', ['1970-10-1', '2000-10-1'])->select();
// 查询两个小时内的博客
Db::name('blog')->whereTime('create_time','-2 hours')->select();
// 查询2017年上半年注册的用户
Db::name('user')->whereBetweenTime('create_time', '2017-01-01', '2017-06-30')->select();
// 查询不是2017年上半年注册的用户
Db::name('user')->whereNotBetweenTime('create_time', '2017-01-01', '2017-06-30')->select();
查询今年注册的用户
Db::name('user')->whereYear('create_time')->select();
Db::name('user')->whereYear('create_time', 'last year')->select();  //去年
Db::name('user')->whereYear('create_time', '2018')->select();  //18年
Db::name('user')->whereMonth('create_time')->select();  //本月
Db::name('user')->whereMonth('create_time','last month')->select();   上月
Db::name('user')->whereMonth('create_time', '2018-06')->select();  //指定月份
Db::name('user')->whereWeek('create_time')->select();  本周
Db::name('user')->whereWeek('create_time', 'last week')->select(); //上周
Db::name('user')->whereDay('create_time')->select(); //当天
Db::name('user')->whereDay('create_time', 'yesterday')->select() 昨天
// 查询2018年6月1日注册的用户
Db::name('user')->whereDay('create_time', '2018-06-01')->select();
// 查询有效期内的活动
Db::name('event')->whereBetweenTimeField('start_time', 'end_time')->select();
Db::table('think_user')->where('name|title','like','thinkphp%')->where('create_time&update_time','>',0)->find();
Db::table('think_user')->where([
['name', 'like', 'thinkphp%'],
['title', 'like', '%thinkphp'],
['id', '>', 0],
['status', '=', 1],
])->select();
闭包查询:
$name = 'thinkphp';
$id = 10;
Db::table('think_user')->where(function ($query) use($name, $id) {
$query->where('name', $name)
->whereOr('id', '>', $id);
})->select();
原生:Db::table('think_user')->whereRaw('id > 0 AND name LIKE "thinkphp%"')->select();
假设数据表 user 中有 email 和nick_name 字段, 我们可以这样来查询。
$user = Db::table('user')
->whereEmail('thinkphp@qq.com')
->find();
// 根据昵称(nick_name) 查询用户
$email = Db::table('user')->whereNickName('like', '%流年%')->select();
// 根据邮箱查询用户信息
$user = Db::table('user')->getByEmail('thinkphp@qq.com');

原生查询:Db::query("select * from think_user where status=:id", ['id' => 1]);
如果希望从主库读取, 可以使用Db::query("select * from think_user where status=:id", ['id' => 1], true);
用于更新和写入:Db::execute("update think_user set name='thinkphp' where status=1");
使用下面的方法注册数据库查询事件
\think\facade\Db::event('before_select', function ($query) {
// 事件处理
// 在这里可以对$query进行操作
$query->where('site_id',1)->order('update_time desc');
$model = $query->getModel(); // 实例化的模型对象,可以给模型自定义一些属性,
在这里读取,相当于传参.
});

事件 描述
before_select select 查询前回调
before_find find 查询前回调
after_insert insert 操作成功后回调
after_update update 操作成功后回调
after_delete delete 操作成功后回调
查询结果过滤:
Db::name('user')->filter(function($user) {
$user['name'] = 'new value';
$user['test'] = 'test';
return $user;
})->select();

比如 MySQL 的 MyISAM 不支持事务处理, 需要使用 InnoDB 引擎。
事务:
Db::transaction(function () {
Db::table('think_user')->find(1);
Db::table('think_user')->delete(1);
});
手动事务:
// 启动事务
Db::startTrans();
try {
      Db::table('think_user')->find(1);
      Db::table('think_user')->delete(1);
// 提交事务
      Db::commit();
} catch (\Exception $e) {
// 回滚事务
      Db::rollback();
}
存储过程:Db::execute('call procedure_name');
存储过程可以支持输入和输出参数, 以及进行参数绑定操作。
$resultSet = Db::query('call procedure_name(:in_param1,:in_param2,:out_param)',
[
'in_param1' => $param1,
'in_param2' => [$param2, PDO::PARAM_INT],
'out_param' => [$outParam, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 4000],
]);

从数据库中select()的数据集,有如下方法:
isEmpty 是否为空
toArray 转换为数组
all 所有数据
merge 合并其它数据
diff 比较数组, 返回差集
flip 交换数据中的键和值
intersect 比较数组, 返回交集
keys 返回数据中的所有键名
pop 删除数据中的最后一个元素
shift 删除数据中的第一个元素
unshift 在数据开头插入一个元素
push 在结尾插入一个元素
reduce 通过使用用户自定义函数, 以字符串返回数组
reverse 数据倒序重排
chunk 数据分隔为多个数据块
each 给数据的每个元素执行回调
filter 用回调函数过滤数据中的元素
column 返回数据中的指定列
sort 对数据排序
order 指定字段排序
shuffle 将数据打乱
slice 截取数据中的一部分
map 用回调函数处理数组中的元素
where 根据字段条件过滤数组中的元素
whereLike Like查询过滤元素
whereNotLike Not Like过滤元素
whereIn IN查询过滤数组中的元素
whereNotIn Not IN查询过滤数组中的元素
whereBetween Between查询过滤数组中的元素
whereNotBetween Not Between查询过滤数组中的元素
模型:
模型会自动对应数据表, 模型类的命名规则是除去表前缀的数据表名称, 采用驼峰法命名, 并且首字母大写
UserType      think_user_type
如果你希望给模型类添加后缀, 需要设置 name 属性或者 table 属性。
protected $pk = 'uid'; 主键
// 设置当前模型对应的完整数据表名称
protected $table = 'think_user';
// 设置当前模型的数据库连接
protected $connection = 'db_config';
// 模型初始化
protected static function init()
{
//TODO:初始化内容
}
用模型查询 :
User::where('id','>',10)->select();
// 定义默认的表后缀(默认查询中文数据)
protected $suffix = _cn';
// 设置模型字段信息
protected $schema = [
'id' => 'int',
'name' => 'string',
'status' => 'int',
'score' => 'float',
'create_time' => 'datetime',
'update_time' => 'datetime',
];

php think optimize:schema
// 设置废弃字段
protected $disuse = [ 'status', 'type' ];
echo $user['name'];

$user = $this->find(1);
echo $user->getAttr('create_time');

$user = new User;
// post数组中只有name和email字段会写入
$user->allowField(['name','email'])->save($_POST);

$user = new User;
// 过滤post数组中的非数据表字段数据
$data = Request::only(['name','email']);
$user->save($data);

$user = User::where('status',1)
->where('name','liuchen')
->find();
$user->name = 'thinkphp';
$user->email = 'thinkphp@qq.com';
$user->save();

User::update(['name' => 'thinkphp', 'id' => 1])
ser::destroy(1);
// 支持批量删除多个数据
User::destroy([1,2,3]);

User::destroy(function($query){
$query->where('id','>',10);
});

$list = User::select([1,2,3]);
// 对数据集进行遍历操作
foreach($list as $key=>$user){
echo $user->name;
}

// 获取某个用户的积分
User::where('id',10)->value('score');
// 获取某个列的所有值
User::where('status',1)->column('name');
// 以id为索引
User::where('status',1)->column('name','id');

模型对象赋值;
调用模型的 data 方法, 并且第二个参数传入 true ;
调用模型的 appendData 方法, 并且第二个参数传入 true ;
调用模型的 save 方法, 并且传入数据;
显式调用模型的 setAttr 方法;
显式调用模型的 setAttrs 方法,效果与 appendData 并传入 true 的用法相同;
public function setNameAttr($value)
{
  return strtolower($value); //设置name属性;
}
模型中定义只读字段:protected $readonly = ['name', 'email'];

// 软删除
User::destroy(1);
// 真实删除
User::destroy(1,true);

如果仅仅需要查询软删除的数据, 可以使用:
User::onlyTrashed()->find();
User::onlyTrashed()->select();

恢复被软删除的数据
$user = User::onlyTrashed()->find(1);
$user->restore();

protected $dateFormat = 'Y/m/d';
protected $type = [
'status' => 'integer',
'score' => 'float',
'birthday' => 'timestamp',
];

// 'birthday' => 'timestamp:Y/m/d',

$user = User::find(1);
View::assign('user', $user);
return View::fetch();

设置不输出的字段属性:$user = User::find(1);
dump($user->hidden(['create_time','update_time'])->toArray());

$user = User::with('profile')->find(1);

$user = User::find(1);
echo $user->toJson();

设置允许输出的属性:
echo $user->visible(['id','name','email'])->toJson();

echo json_encode(User::find(1));

模型事件 描述 事件方法名
after_read 查询后 onAfterRead
before_insert 新增前 onBeforeInsert
after_insert 新增后 onAfterInsert
before_update 更新前 onBeforeUpdate
after_update 更新后 onAfterUpdate
before_write 写入前 onBeforeWrite
after_write 写入后 onAfterWrite
before_delete 删除前 onBeforeDelete
after_delete 删除后 onAfterDelete
before_restore 恢复前 onBeforeRestore
after_restore 恢复后 onAfterRestore

class User extends Model
{
public function profile()
{
     return $this->hasOne(Profile::class);
}
}
类型 关联关系 相对的关联关系
一对一 hasOne belongsTo
一对多 hasMany belongsTo
多对多 belongsToMany belongsToMany
远程一对多 hasManyThrough 不支持
多态一对一 morphOne morphTo
多态一对多 morphMany morphTo
class Profile extends Model
{
public function user()
{
     return $this->belongsTo(User::class);
}
}

$profile = Profile::find(1);
// 获取档案所属的用户名称
echo $profile->user->name; //二个表己经关联;

hasOne('关联模型类名', '外键', '主键');
return $this->hasOne(Profile::class, 'uid');


withJoin 方法默认使用的是 INNER JOIN 方式, 如果需要使用其它的, 可以改成
$users = User::withJoin('profile', 'LEFT')->select();
foreach ($users as $user) {
echo $user->profile->name;
}

belongsTo('关联模型','外键', '关联主键');

$user = User::find(1)->bindAttr('profile',['email','nickname']);
// 输出Profile关联模型的email属性
echo $user->email;
echo $user->nickname;

// 查询评论超过3个的文章
$list = Article::has('comments','>',3)->select();
// 查询评论状态正常的文章
$list = Article::hasWhere('comments',['status'=>1])->select();

hasManyThrough('关联模型', '中间模型', '外键', '中间表关联键','当前模型主键','中间模型主键');
通常可以直接使用 think\facade\View 来操作视图。
View::assign('email','thinkphp@qq.com');
// 或者批量赋值
View::assign([
'name' => 'ThinkPHP',
'email' => 'thinkphp@qq.com'
]);
// 模板输出
return View::fetch('index');
助手函数:
return view('index', [
'name' => 'ThinkPHP',
'email' => 'thinkphp@qq.com'
]);

// 使用视图输出过滤
return View::filter(function($content){
return str_replace("\r\n",'<br/>',$content);
})->fetch();

// 不带任何参数 自动定位当前操作的模板文件
return View::fetch();

return View::fetch('admin@member/edit');
return View::fetch('../template/public/menu.html');

如果希望直接解析内容而不通过模板文件的话, 可以使用 display 方法:
return View::display($content, ['name' => 'thinkphp', 'email' => 'think
php@qq.com']);
}

// 使用内置PHP模板引擎渲染模板输出
return View::engine('php')->fetch();

protected $schema = [
'id' => 'int',
'name' => 'string',
'status' => 'int',
'score' => 'float',
'create_time' => 'datetime',
'update_time' => 'datetime',
];

需要在数据库配置中设置 fields_cache 为 true 才能生成缓存,schema 属性一旦定义, 就必须定义完整的数据表字段类型。
// 设置字段自动转换类型   protected $type = ['score' => 'float',];

$user = new User;
$list = [['name'=>'thinkphp','email'=>'thinkphp@qq.com'],['name'=>'onethink','email'=>'onethink@qq.com']];
$user->saveAll($list);
// 只允许写入name和email字段的数据  create 方法默认会过滤不是数据表的字段信息, 可以在第二个参数可以传入允许写入的字段列表
$user = User::create([
'name' => 'thinkphp',
'email' => 'thinkphp@qq.com'
], ['name', 'email']);
echo $user->name;
echo $user->email;
echo $user->id; // 获取自增ID
更新:
User::update(['name' => 'thinkphp', 'id' => 1]);

如果你是在模型内部获取数据, 请不要使用 $this->name 的方式来获取数据, 请使用$this->getAttr('name') 替代。
// 获取某个用户的积分
User::where('id',10)->value('score');
// 获取某个列的所有值
User::where('status',1)->column('name');
// 以id为索引
User::where('status',1)->column('name','id');
动态查询:
// 根据name字段查询用户
$user = User::getByName('thinkphp');
// 根据email字段查询用户
$user = User::getByEmail('thinkphp@qq.com');

User::max('score');
如果在模型中定义:
class User extends Model
{
public function scopeThinkphp($query)
{
      $query->where('name','thinkphp')->field('id,name');
}
public function scopeAge($query)
{
      $query->where('age','>',20)->limit(10);
}
}
就可以用动态查询:
// 查找name为thinkphp的用户
User::scope('thinkphp')->find();
// 查找年龄大于20的10个用户
User::scope('age')->select();
// 查找name为thinkphp的用户并且年龄大于20的10个用户
User::scope('thinkphp,age')->select()

// 设置json类型字段
protected $json = ['info'];

$user->info = [
'email' => 'thinkphp@qq.com',
'nickname '=> '流年',
];
$user = User::where('info->nickname','流年')->find();

protected $jsonType = [
'info->user_id' => 'int'
];

搜索器的作用是用于封装字段( 或者搜索标识) 的查询条件表达式, 一个搜索器对应一个特殊的方法( 该方法必
须是 public 类型) , 方法命名规范为:
search FieldName Attr
public function searchNameAttr($query, $value, $data)
{
$query->where('name','like', $value . '%');
}
然后可以用下面的语句搜索:
User::withSearch(['name','create_time'], [
'name' => 'think',
'create_time' => ['2018-8-1','2018-8-5'],
'status' => 1
])->select();

// 开启自动写入时间戳字段 配置:
'auto_timestamp' => 'datetime',
在模型类中:protected $autoWriteTimestamp = 'datetime';
系统会自动写入 create_time 和 update_time 字段
// 定义时间戳字段名
protected $createTime = 'create_at';
protected $updateTime = 'update_at';
在数据库中统一定义时间字段:
'datetime_field' => 'create_at,update_at',
模型中用于监听事件的:
public static function onBeforeUpdate($user)
{
if ('thinkphp' == $user->name) {
return false;
}
} //如果事件没有返回`false`,那么继续执行
public static function onAfterDelete($user)
{
Profile::destroy($user->id);
}
有的事件:如果事件没有返回`false`,那么继续执行;

模型关联操作把数据表的关联关系对象化, 解决了大部分常用的关联场景, 封装的关联操作比起常规的数据库联表操作更加智能和高效, 并且直观。hasOne('关联模型类名', '外键', '主键');
public function profile()
{
    return $this->hasOne(Profile::class);   //hasOne('关联模型类名', '外键', '主键');user_id为外键,如果不是则是uid;
}
echo $user->profile->phone;   这样可以使用profile字段;
另一个属于:return $this->belongsTo(User::class);
有这种关系的查询:$users = User::hasWhere('profile', ['nickname'=>'think'])->select();
$user = User::with('profile')->select();//User 模型类有profile函数;这个函数有hasone
// 注意第一个参数是关联方法名(不是关联模型名)
$users = User::hasWhere('profile', ['nickname'=>'think'])->select();

belongsTo('关联模型','外键', '关联主键');

class Profile extends Model
{
public function user()
{
    return $this->belongsTo(User::class, 'uid'); //belongsTo('关联模型','外键', '关联主键');
}
}

$user = User::with('books')->find(1);
// 直接输出Profile关联模型的绑定属性
echo $user->email;
echo $user->truename;
由于是toMany,所有,不能直接写属性,返回的是数组:echo $user->books[0]->bookname;
动态绑定关联属性;
$user = User::find(1)->bindAttr('profile',['email','nickname']);
// 输出Profile关联模型的email属性
echo $user->email;
echo $user->nickname;

// 查询
$blog = Blog::find(1);
$blog->title = '更改标题';
$blog->content->data = '更新内容';
// 更新当前模型及关联模型
$blog->together(['content'])->save();

// 查询
$blog = Blog::with('content')->find(1);
// 删除当前及关联模型
$blog->together(['content'])->delete();
进行二次搜索:
$user->books()->where('id',2)->select()

// 查询评论超过3个的文章
$list = Article::has('comments','>',3)->select();
// 查询评论状态正常的文章
$list = Article::hasWhere('comments',['status'=>1])->select();

$where = Comment::where('status',1)->where('content', 'like', '%think%');
$list = Article::hasWhere('comments', $where)->select();
关联新增:
$article = Article::find(1);
// 增加一个关联数据
$article->comments()->save(['content'=>'test']);
// 批量增加关联数据
$article->comments()->saveAll([
    ['content'=>'thinkphp'],
    ['content'=>'onethink'],
]);

关联删除
在删除文章的同时删除下面的评论
$article = Article::with('comments')->find(1);
$article->together(['comments'])->delete();

多对多关联
belongsToMany('关联模型','中间表','外键','关联键');
return $this->belongsToMany(Role::class, 'access');
多对多关联
class User extends Model
{
public function roles()
{
    return $this->belongsToMany(Role::class, 'access');
    //belongsToMany('关联模型','中间表','外键','关联键');
   //return $this->belongsToMany(Role::class, Access::class);
}
}

关联新增
$user = User::find(1);
// 给用户增加管理员权限 会自动写入角色表和中间表数据
$user->roles()->save(['name'=>'管理员']);
// 批量授权
$user->roles()->saveAll([
['name'=>'管理员'],
['name'=>'操作员'],
]);    

$user = User::find(1);
// 仅增加管理员权限(假设管理员的角色ID是1)
$user->roles()->save(1);
// 或者
$role = Role::find(1);
$user->roles()->save($role);
// 批量增加关联数据
$user->roles()->saveAll([1,2,3]);

定义相对的关联:
class Role extends Model
{
public function users()
{
    return $this->belongsToMany(User::class, Access::class);
}
}
果你的数据集查询返回的是数据集对象, 可以使用调用数据集对象的 load 实现延迟预载入:
// 查询数据集
$list = User::select([1,2,3]);
// 延迟预载入
$list->load(['cards']);
foreach($list as $user){
// 获取用户关联的card模型数据
dump($user->cards);
}

$list = User::with(['profile'])->withCache(30)->select([1,2,3]);

// 查询数据集
$list = User::select([1,2,3]);
// 延迟预载入
$list->load(['cards'], 30);   //30秒

return View::fetch('admin@member/edit'); //跨应用渲染模板

public function index()
{
// 改变当前操作的模板路径
View::config(['view_path' => 'mypath']);
return View::fetch();
}

日志:
Log::error('错误信息');
Log::info('日志信息')
trace('错误信息', 'error');
trace('日志信息', 'info');
Log::info('日志信息{user}', ['user' => '流年']);
Log::clear(); //手动清空日志
验证:
php think make:validate User //建立User验证
protected $rule = [
'name' => 'require|max:25',
'email' => 'email',
];
---------------------
try {
      validate(User::class)->check([
      'name' => 'thinkphp',
      'email' => 'thinkphp@qq.com',
]);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
      dump($e->getError());
}
------------------------------
protected $rule = [
'name' => ['require', 'max' => 25, 'regex' => '/^[\w|\d]\w+/'],
'age' => ['number', 'between' => '1,120'],
'email' => 'email',
];
-----------------------------
use think\facade\Validate;
use think\validate\ValidateRule as Rule;
$validate = Validate::rule('age', Rule::isNumber()->between([1,120]))
->rule([
'name' => Rule::isRequire()->max(25),
'email' => Rule::isEmail(),
]);
$data = [
'name' => 'thinkphp',
'email' => 'thinkphp@qq.com'
];
if (!$validate->check($data)) {
dump($validate->getError());
}
定义验证场景:
protected $scene = [
'edit' => ['name','age'],
];

try {
  validate(app\validate\User::class)->scene('edit')->check($data);
} catch (ValidateException $e) {
  dump($e->getError());
}
路由验证:
Route::post('hello/:id', 'index/hello')
->validate([
'name' => 'min:5|max:50',
'email' => 'email',
]);
对象化规则:
Route::post('hello/:id', 'index/hello')
->validate(['name' => ValidateRule::min(5)->max(50),'email' => ValidateRule::isEmail(),]);
内置验证规则 :
require | number | integer | float | boolean | email | array | accepted  (yes,on,1)
date | alpha(纯字母) | alphaNum(字母与数字) | chs (汉字)
cntrl 控制字符( 换行、 缩进、 空格)
lower upper 大小写 space 空格 xdigit 16进制
activeUrl(有效域名与IP)url   ip
dateFormat:format   'create_time'=>'dateFormat:y-m-d'  验证日期格式
mobile 验证有效手机  idCard 身份证号 macAddr 网卡地址 zip 邮编
'num'=>'in:1,2,3'     //in not in 范围
'num'=>'between:1,10'  //区间
'name'=>'length:4,25' //长度区间
'name'=>'max:25'  //最大长度 'name'=>'min:5  最小长度
'begin_time' => 'after:2016-3-18',  'end_time' => 'before:2016-10-01',  某段时间前,某段时间后
'expire_time' => 'expire:2016-2-1,2016-10-01', 验证当前操作( 注意不是某个值) 是否在某个有效日期之内
'name' => 'allowIp:114.45.4.55'  验证当前请求的IP是否在某个范围
验证某个字段是否和另外一个字段的值一致, 例如:'repassword'=>'require|confirm:password'
'password'=>'require|confirm' 会自动验证和 password_confirm 进行字段比较是否一致, 反之亦然。
验证某个字段是否和另外一个字段的值不一致, 例如:'name'=>'require|different:account'
'score'=>'eq:100'    //等于100      'num'=>'=:100'   'num'=>'same:100'
'score'=>'egt:60'     'num'=>'>=:100'    大于等于
'score'=>'gt:60'   'num'=>'>:100  大于
'score'=>'elt:100' 'num'=>'<=:100'   小于
正则验证'zip'=>'\d{6}'
上传验证: file  
image:width,height,type验证是否是一个图像文件, width height和type都是可选, width和height必须同时定义。
fileExt:允许的文件后缀 验证上传文件后缀 fileMime:允许的文件类型验证上传文件类型fileSize:允许的文件字节大小
表单验证:
// 表示验证name字段的值是否在user表(不包含前缀) 中唯一
'name' => 'unique:user',
// 验证其他字段
'name' => 'unique:user,account',
// 排除某个主键值
'name' => 'unique:user,account,10',
// 指定某个主键值排除
'name' => 'unique:user,account,10,user_id',
缓存:
Cache::set('name', $value, new DateTime('2019-10-01 12:00:00'));
Cache::inc('name',3);

Cache::get('name');
Cache::get('name','')
数组缓存:Cache::set('name', [1,2,3]);
Cache::push('name', 4);
Cache::get('name'); // [1,2,3,4]
Cache::delete('name');

Cache::pull('name');
Cache::clear();

Cache::remember('start_time', time());

助手函数:
cache('name', $value, 3600);     // cache('name')
// 使用文件缓存
Cache::set('name','value',3600);
Cache::get('name');
// 使用Redis缓存
Cache::store('redis')->set('name','value',3600);
Cache::store('redis')->get('name');
// 切换到文件缓存
Cache::store('default')->set('name','value',3600);
Cache::store('default')->get('name');

Session::set('name', 'thinkphp');
Session::get('name');
Session::has('name');
/ 如果值不存在, 返回null
Session::get('name');
// 如果值不存在, 返回空字符串
Session::get('name', '');
// 获取全部数据
Session::all();
Session::delete('name');
// 取值并删除
Session::pull('name');

Session::clear();  清空
// 设置session 并且在下一次请求之前有效
Session::flash('name','value');
// 清除当前请求有效的session
Session::flush();
// 赋值
Session::set('name.item','thinkphp');
// 判断是否赋值
Session::has('name.item');
// 取值
Session::get('name.item');
// 删除
Session::delete('name.item');
session助手函数:
// 赋值
session('name', 'thinkphp');
// 判断是否赋值
session('?name');
// 取值
session('name');
// 删除
session('name', null);
// 清除session
session(null);

可以在Request对象中读取Session数据
public function index(Request $request) {
// 读取某个session数据
$request->session('user.name', '');
// 获取全部session数据
$request->session();
}

cookie:
// 设置Cookie 有效期为 3600秒
Cookie::set('name', 'value', 3600);
Cookie::forever('name', 'value');
Cookie::delete('name');

// 读取某个cookie数据
Cookie::get('name');
// 获取全部cookie数据
Cookie::get();

// 设置
cookie('name', 'value', 3600);
// 获取
echo cookie('name');
// 删除
cookie('name', null);
上传文件:
public function upload(){
// 获取表单上传文件 例如上传了001.jpg
    $file = request()->file('image');
    // 上传到本地服务器
    $savename = \think\facade\Filesystem::putFile( 'topic', $file);
                //$savename = \think\facade\Filesystem::putFile( 'topic', $file, 'md5'); //md5命名方式 1 date md5 sha1
}
$savename = \think\facade\Filesystem::disk('public')->putFile( 'topic', $file);   //位置
$savename = \think\facade\Filesystem::putFileAs( 'topic', $file,'abc.jpg'); //改名

批量上传:
<form action="/index/index/upload" enctype="multipart/form-data" method="post">
<input type="file" name="image[]" /> <br>
<input type="file" name="image[]" /> <br>
<input type="file" name="image[]" /> <br>
<input type="submit" value="上传" />
</form>
public function upload(){
// 获取表单上传文件
$files = request()->file('image');
$savename = [];
foreach($files as $file){
    $savename[] = \think\facade\Filesystem::putFile( 'topic', $file);
}
}
------------------------
public function upload(){
// 获取表单上传文件
    $files = request()->file();
    try {
        validate(['image'=>'fileSize:10240|fileExt:jpg|image:200,200,jpg'])->check($files);
        $savename = [];
    foreach($files as $file) {
        $savename[] = \think\facade\Filesystem::putFile( 'topic', $file);
    }
    } catch (\think\exception\ValidateException $e) {
        echo $e->getMessage();
    }
}

获取文件的sha1:
echo $file->hash('sha1');
echo $file->hash('md5');

php think build admin //快速生成 admin 应用

php think make:controller index@Blog
php think make:controller Blog

php think clear   清缓存

php think optimize:route 生存路由映射缓存

php think route:list admin    //查看多路由映射

workman:
composer require topthink/think-worker
php think worker

php think worker:server
think助手工具库
composer require topthink/think-helper
验证码:
<div>{:captcha_img()}</div>
<div><img src="{:captcha_src()}" alt="captcha" /></div>
注意一定要打开sessionInit::class中间件,否则验证不了;
$captcha = input('captcha');
    if( !captcha_check($captcha )){
        return '验证码错误';
    }else{
        return '验证码正确';
    }
就这,就可以了;
Swoole: 仅支付linux运行:
composer require topthink/think-swoole

登录 :
public function index()
这个后台的主页控制器首页:
if(session('adminSessionData')){
            return redirect('/qingadmin/index');
}
如果有session,则转向 后台首页,如果没有session,说明没有登录,这时,要检测登录;if (request()->isPost()) { 说明己经提交了表单过来 }己经传过来,说明只需要验证:这时,处理验证:验证验证码,读数据,数据查询,有数据验证密码。验证帐号是否禁用,然后session('adminSessionData', $adminData);加session存盘,然后,return alert('登录成功', '/qingadmin/index/index', 6); 提示 然后转向,否则,说明即没登录 ,又没提交,这时,转到view(login)登录页就可以了;
session('adminSessionData',null);  登出
return redirect('/qingadmin/login/index');然后退出转向;
中间件:
public function handle($request, \Closure $next)
    {
        if(empty(session('adminSessionData')) && !preg_match('/login/',$request->pathinfo())){
            return redirect((string) url('login/index'));
        }
        return $next($request);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值