Thinkphp6.0文档部分摘抄
从宝塔到tp5.0的各种配置:https://www.cnblogs.com/BigBender/p/14316511.html
Thinkphp6.0和Tp5差别还是蛮大的,从常用的点出发摘抄一下
跨域处理
在路由上使用内置的跨域中间件
官方地址:https://www.kancloud.cn/manual/thinkphp6_0/1037507
Route::get('new/:id', 'News/read') ->ext('html') ->allowCrossDomain();
跨域请求一般会发送一条OPTIONS
的请求,一旦设置了跨域请求的话,不需要自己定义OPTIONS
请求的路由,系统会自动加上。
跨域请求系统会默认带上一些Header,包括:
Access-Control-Allow-Origin:* Access-Control-Allow-Methods:GET, POST, PATCH, PUT, DELETE Access-Control-Allow-Headers:Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With
你可以添加或者更改Header信息,使用
Route::get('new/:id', 'News/read') ->ext('html') ->allowCrossDomain([ 'Access-Control-Allow-Origin' => 'thinkphp.cn', 'Access-Control-Allow-Credentials' => 'true' ]);
V6.0.3+
版本开始增加了默认的预检缓存有效期(默认为30分钟),你可以自定义有效期,例如:
Route::get('new/:id', 'News/read') ->ext('html') ->allowCrossDomain([ 'Access-Control-Allow-Origin' => 'thinkphp.cn', 'Access-Control-Allow-Credentials' => 'true', 'Access-Control-Max-Age' => 600, ]);
注册服务实现跨域
官方地址:https://www.kancloud.cn/manual/thinkphp6_0/1037490
register和boot,个人理解register是服务的前置事件,boot就是服务内容
可以通过命令行创建服务类
php think make:service CrossDomainService
我的跨域服务
<?php declare (strict_types = 1); namespace app\service; class CrossDomainService extends \think\Service { /** * 注册服务 * * @return mixed */ public function register() { // } /** * 执行服务 * * @return mixed */ public function boot() { header('Access-Control-Allow-Origin: *'); header("Access-Control-Allow-Headers: token,Origin, X-Requested-With, Content-Type, Accept"); header("Access-Control-Allow-Methods:GET, POST, OPTIONS, DELETE"); if (request()->isOptions()) { exit(); } } }
别忘了手动添加到service.php
<?php use app\AppService; use app\service\CrossDomainService; // 系统服务定义文件 // 服务在完成全局初始化之后执行 return [ AppService::class, CrossDomainService::class ];
通过事件绑定实现跨域
官方地址:https://www.kancloud.cn/manual/thinkphp6_0/1037492
通过命令行快速生成事件
php think make:event CrossDomain
数据迁移工具
官方地址:https://www.kancloud.cn/manual/thinkphp6_0/1118028
composer require topthink/think-migration
创建
php think migrate:create TestClass
示例
<?php use think\migration\Migrator; use think\migration\db\Column; class AnyClassNameYouWant extends Migrator { /** * Change Method. * * Write your reversible migrations using this method. * * More information on writing migrations is available here: * http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class * * The following commands can be used in this method and Phinx will * automatically reverse them when rolling back: * * createTable * renameTable * addColumn * renameColumn * addIndex * addForeignKey * * Remember to call "create()" or "update()" and NOT "save()" when working * with the Table class. */ public function change() { // create the table $table = $this->table('users',array('engine'=>'MyISAM')); $table->addColumn('username', 'string',array('limit' => 15,'default'=>'','comment'=>'用户名,登陆使用')) ->addColumn('password', 'string',array('limit' => 32,'default'=>md5('123456'),'comment'=>'用户密码')) ->addColumn('login_status', 'boolean',array('limit' => 1,'default'=>0,'comment'=>'登陆状态')) ->addColumn('login_code', 'string',array('limit' => 32,'default'=>0,'comment'=>'排他性登陆标识')) ->addColumn('last_login_ip', 'integer',array('limit' => 11,'default'=>0,'comment'=>'最后登录IP')) ->addColumn('last_login_time', 'datetime',array('default'=>0,'comment'=>'最后登录时间')) ->addColumn('is_delete', 'boolean',array('limit' => 1,'default'=>0,'comment'=>'删除状态,1已删除')) ->addIndex(array('username'), array('unique' => true)) ->create(); } }
执行迁移工具
php think migrate:run
表支持参数
选项 | 描述 |
---|---|
comment | 给表结构设置文本注释 |
row_format | 设置行记录模格式 |
engine | 表引擎 (默认 InnoDB ) |
collation | 表字符集 (默认 utf8\_general\_ci ) |
signed | 是否无符号 signed (默认 true ) |
常用列
- biginteger
- binary
- boolean
- date
- datetime
- decimal
- float
- integer
- string
- text
- time
- timestamp
- uuid
所有类型支持的参数
Option | Description |
---|---|
limit | 文本或者整型的长度 |
length | limit 别名 |
default | 默认值 |
null | 允许 NULL 值 (不该给主键设置 |
after | 在哪个字段名后 (只对MySQL有效) |
comment | 给列设置文本注释 |
添加索引
->addIndex(['email','username'], ['limit' => ['email' => 5, 'username' => 2]]) ->addIndex('user_guid', ['limit' => 6]) ->addIndex('email',['type'=>'fulltext'])
自动升降级
如果希望实现自动升级降级,那就把逻辑写在change方法里,只最终调用create
和update
方法,不要调用save
方法
change
方法内仅支持以下操作
- createTable
- renameTable
- addColumn
- renameColumn
- addIndex
- addForeignKey
如果真的有调用其他方法,可以写到up
和down
方法里,这里的逻辑不支持自动还原,up写升级的逻辑,down写降级的逻辑
public function change() { // create the table $table = $this->table('user_logins'); $table->addColumn('user_id', 'integer') ->addColumn('created', 'datetime') ->create(); } /** * Migrate Up. */ public function up() { } /** * Migrate Down. */ public function down() { }
路由
需要使用门面
use think\facade\Route;
注册路由
Route::rule('new/:id','News/read');
快捷方法
类型 | 描述 | 快捷方法 |
---|---|---|
GET | GET请求 | get |
POST | POST请求 | post |
PUT | PUT请求 | put |
DELETE | DELETE请求 | delete |
PATCH | PATCH请求 | patch |
* | 任何请求类型 | any |
示例
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('blog/:id','blog/read')
->append(['status' => 1, 'app_id' =>5]);
路由标识
Route::rule('new/:id','News/read')
->name('new_read');
动态路由
// 定义动态路由 Route::get('hello/:name', 'index/:name/hello');
路由到控制器
路由到控制器
// 路由到blog控制器 Route::get('blog/:id','Blog/read'); // Blog控制器 <?php namespace app\index\controller; class Blog { public function read($id) { return 'read:' . $id; } }
路由到类
使用@标识
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', ['city'=>'shanghai']);
路由到闭包+依赖注入
Route::rule('hello/:name', function (Request $request, $name) { $method = $request->method(); return '[' . $method . '] Hello,' . $name; });
路由到调度方法
// 路由到自定义调度对象 Route::get('blog/:id',\app\route\BlogDispatch::class); // 调度方法 namespace app\route; use think\route\Dispatch; use think\route\Rule; use think\Request; class BlogDispatch extends Dispatch { public function exec() { // 自定义路由调度 } }
路由参数
参数 | 说明 | 方法名 |
---|---|---|
ext | URL后缀检测,支持匹配多个后缀 | ext |
deny_ext | URL禁止后缀检测,支持匹配多个后缀 | denyExt |
https | 检测是否https请求 | https |
domain | 域名检测 | domain |
complete_match | 是否完整匹配路由 | completeMatch |
model | 绑定模型 | model |
cache | 请求缓存 | cache |
ajax | Ajax检测 | ajax |
pjax | Pjax检测 | pjax |
json | JSON检测 | json |
validate | 绑定验证器类进行数据验证 | validate |
append | 追加额外的参数 | append |
middleware | 注册路由中间件 | middleware |
filter | 请求变量过滤 | filter |
路由中间件
可以使用路由中间件,注册方式如下
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::rule('hello/:name','hello') ->middleware(\app\middleware\Auth::class,'admin');
定义多个中间件,使用数组方式
Route::rule('hello/:name','hello') ->middleware([\app\middleware\Auth::class,\app\middleware\Check::class]);
统一传入同一个额外参数
Route::rule('hello/:name','hello') ->middleware([\app\middleware\Auth::class, \app\middleware\Check::class], 'admin');
如果你希望某个路由中间件是全局执行(不管路由是否匹配)
在文件config/route.php中配置
'middleware' => [ app\middleware\Auth::class, app\middleware\Check::class, ],
注解路由
安装依赖
composer require topthink/think-annotation
示例
<?php namespace app\controller; use think\annotation\Route; class Index { /** * @param string $name 数据名称 * @return mixed * @Route("hello/:name") */ public function hello($name) { return 'hello,'.$name; } }
@Route("hello/:name")
就是注解路由的内容
<?php namespace app\controller; use think\annotation\Route; class Index { /** * @param string $name 数据名称 * @Route('hello/:name', method="GET", https=1, ext="html") * @return mixed */ public function hello($name) { return 'hello,'.$name; } }
路由绑定
// 绑定当前的URL到 Blog控制器 Route::bind('blog'); // 绑定当前的URL到 Blog控制器的read操作 Route::bind('blog/read');
绑定到命名空间
// 绑定命名空间 Route::bind(':\app\index\controller');
绑定到类
// 绑定到类 Route::bind('\app\index\controller\Blog');
域名路由
Route::domain('blog', function () { // 动态注册域名的路由规则 Route::rule('new/:id', 'news/read'); Route::rule(':user', 'user/info'); });
支持多个子域名
Route::domain(['blog', 'admin'], function () { // 动态注册域名的路由规则 Route::rule('new/:id', 'news/read'); Route::rule(':user', 'user/info'); });
如果你需要设置一个路由跨所有域名都可以生效,可以对分组路由或者某个路由使用crossDomainRule
方法设置
Route::group( function () { // 动态注册域名的路由规则 Route::rule('new/:id', 'news/read'); Route::rule(':user', 'user/info'); })->crossDomainRule();
控制器中间件
<?php namespace app\controller; use app\middleware\Auth; class Index { protected $middleware = [Auth::class]; public function index() { return 'index'; } public function hello() { return 'hello'; } }
请求
构造方法注入
<?php namespace app\index\controller; use think\Request; class Index { /** * @var \think\Request Request实例 */ protected $request; /** * 构造方法 * @param Request $request Request对象 * @access public */ public function __construct(Request $request) { $this->request = $request; } public function index() { return $this->request->param('name'); } }
操作方法注入
<?php namespace app\index\controller; use think\Request; class Index { public function index(Request $request) { return $request->param('name'); } }
静态调用
<?php namespace app\index\controller; use think\facade\Request; class Index { public function index() { return Request::param('name'); } }
助手函数
<?php namespace app\index\controller; class Index { public function index() { return request()->param('name'); } }
请求信息
use think\facade\Request; // 获取完整URL地址 不带域名 Request::url(); // 获取完整URL地址 包含域名 Request::url(true); // 获取当前URL(不含QUERY_STRING) 不带域名 Request::baseFile(); // 获取当前URL(不含QUERY_STRING) 包含域名 Request::baseFile(true); // 获取URL访问根地址 不带域名 Request::root(); // 获取URL访问根地址 包含域名 Request::root(true);
方法 | 含义 |
---|---|
host |
当前访问域名或者IP |
scheme |
当前访问协议 |
port |
当前访问的端口 |
remotePort |
当前请求的REMOTE_PORT |
protocol |
当前请求的SERVER_PROTOCOL |
contentType |
当前请求的CONTENT_TYPE |
domain |
当前包含协议的域名 |
subDomain |
当前访问的子域名 |
panDomain |
当前访问的泛域名 |
rootDomain |
当前访问的根域名 |
url |
当前完整URL |
baseUrl |
当前URL(不含QUERY_STRING) |
query |
当前请求的QUERY_STRING参数 |
baseFile |
当前执行的文件 |
root |
URL访问根地址 |
rootUrl |
URL访问根目录 |
pathinfo |
当前请求URL的pathinfo信息(含URL后缀) |
ext |
当前URL的访问后缀 |
time |
获取当前请求的时间 |
type |
当前请求的资源类型 |
method |
当前请求类型 |
rule |
当前请求的路由对象实例 |
获取当前控制器
Request::controller();
获取当前操作
Request::action();
Request变量
检查变量是否设置
Request::has('id','get');
Request::has('name','post');
param | 获取当前请求的变量 |
get | 获取 $_GET 变量 |
post | 获取 $_POST 变量 |
put | 获取 PUT 变量 |
delete | 获取 DELETE 变量 |
session | 获取 SESSION 变量 |
cookie | 获取 $_COOKIE 变量 |
request | 获取 $_REQUEST 变量 |
server | 获取 $_SERVER 变量 |
env | 获取 $_ENV 变量 |
route | 获取 路由(包括PATHINFO) 变量 |
middleware | 获取 中间件赋值/传递的变量 |
file | 获取 $_FILES 变量 |
系统推荐Param变量
// 获取当前请求的name变量 Request::param('name'); // 获取当前请求的所有变量(经过过滤) Request::param(); // 获取当前请求未经过滤的所有变量 Request::param(false); // 获取部分变量 Request::param(['name', 'email']);
变量过滤
namespace app; class Request extends \think\Request { protected $filter = ['htmlspecialchars']; }
过滤方法
Request::get('name','','htmlspecialchars'); // 获取get变量 并用htmlspecialchars函数过滤 Request::param('username','','strip_tags'); // 获取param变量 并用strip_tags函数过滤 Request::post('name','','org\Filter::safeHtml'); // 获取post变量 并用org\Filter类的safeHtml方法过滤
only只获取需要的变量
// 只获取GET请求的id和name变量 Request::only(['id','name'], 'get'); // 等效于 Request::get(['id', 'name']); // 只获取POST请求的id和name变量 Request::only(['id','name'], 'post'); // 等效于 Request::post(['id', 'name']);
排除变量
// 排除GET请求的id和name变量 Request::except(['id','name'], 'get'); // 排除POST请求的id和name变量 Request::except(['id','name'], 'post');
助手函数input
input('param.name'); // 获取单个参数 input('param.'); // 获取全部参数 // 下面是等效的 input('name'); input('');
请求类型
用途 | 方法 |
---|---|
获取当前请求类型 | method |
判断是否GET请求 | isGet |
判断是否POST请求 | isPost |
判断是否PUT请求 | isPut |
判断是否DELETE请求 | isDelete |
判断是否AJAX请求 | isAjax |
判断是否PJAX请求 | isPjax |
判断是否JSON请求 | isJson |
判断是否手机访问 | isMobile |
判断是否HEAD请求 | isHead |
判断是否PATCH请求 | isPatch |
判断是否OPTIONS请求 | isOptions |
判断是否为CLI执行 | isCli |
判断是否为CGI模式 | isCgi |
表单伪装请求类型
<form method="post" action=""> <input type="text" name="name" value="Hello"> <input type="hidden" name="_method" value="PUT" > <input type="submit" value="提交"> </form>
http头信息
$info = Request::header(); echo $info['accept']; echo $info['accept-encoding']; echo $info['user-agent'];
伪静态
在route.php中配置,方便seo
// 默认情况下,伪静态的设置为html,如果我们设置伪静态后缀为空字符串, 'url_html_suffix'=>''
// 关闭伪静态后缀访问 'url_html_suffix' => false,
// 多个伪静态后缀设置 用|分割 'url_html_suffix' => 'html|shtml|xml'
请求缓存,仅对GET有效
// 定义GET请求路由规则 并设置3600秒的缓存 Route::get('new/:id','News/read')->cache(3600);
// 定义GET请求路由规则 并设置3600秒的缓存 Route::get('new/:id','News/read')->cache( [ 'new/:id/:page', 3600] );
全局请求缓存
如果需要开启全局请求缓存,只需要在全局(或者应用)的中间件定义文件middleware.php
中增加
'think\middleware\CheckRequestCache',
然后只需要在route.php
配置文件中设置全局缓存的有效时间(秒):
'request_cache_expire' => 3600,
就会自动根据当前请求URL地址(只针对GET请求类型)进行请求缓存,全局缓存有效期为3600秒。
如果需要对全局缓存设置缓存规则,可以直接设置request_cache_key
参数,例如:
'request_cache_key' => '__URL__', 'request_cache_expire' => 3600,
睁开眼,书在面前 闭上眼,书在心里