Loading

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

所有类型支持的参数

OptionDescription
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方法里,只最终调用createupdate方法,不要调用save方法

change方法内仅支持以下操作

  • createTable
  • renameTable
  • addColumn
  • renameColumn
  • addIndex
  • addForeignKey

如果真的有调用其他方法,可以写到updown方法里,这里的逻辑不支持自动还原,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,
posted @ 2021-04-02 15:07  BigBender  阅读(175)  评论(0编辑  收藏  举报