Loading

linux + 宝塔 + thinkphp5.0 搭建后端api各种问题集合

安装宝塔

官方地址:https://www.bt.cn/bbs/thread-19376-1-1.html

我用的centos 7 所以有以下指令

yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh

安装完毕,记下我们服务器的宝塔账号和密码

然后登陆宝塔,在软件商店中安装nginx + php,我用的云数据库,所以没有安装mysql

 然后我们去安装thinkphp 5,官方地址:https://www.kancloud.cn/manual/thinkphp5/118006

Composer安装

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

用composer安装别忘了更改镜像源,国内镜像源比较快

composer config -g repo.packagist composer https://packagist.phpcomposer.com

然后到web根目录下去执行

composer create-project topthink/think=5.0.* tp5  --prefer-dist

compser过程中putenv、proc_open被禁用和版本报错

去宝塔的软件商店设置一下php禁用函数

找到putenv然后删除

同理,解除proc_open禁用

版本报错

替换镜像源即可

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

php启动服务过程中passthru被禁用

在宝塔中解除禁用即可

Git安装

亲测,码云的这个已经不能用了

 直接用github的,稍微慢一点

git clone https://github.com/top-think/think tp5
git clone https://github.com/top-think/framework thinkphp

然后进入thinkphp目录,切换核心库到master分支

cd thinkphp
git checkout master
git pull https://github.com/top-think/framework

上述步骤结束,tp5就安装完成了,然后我们去宝塔配置下nginx

到网站选项添加站点

点设置打开配置文件

在51行添加以下代码来支持tp的pathinfo

location / {
    try_files $uri $uri/ /index.php$is_args$args;
    if (!-e $request_filename) {
        rewrite ^(.*)$ /index.php?s=$1 last;
        break;
    }
}

 如果有证书的话,下载下来配置ssl

然后去网站目录更改运行目录为框架低下的public目录

至此宝塔这部分结束

tp5在linux下的权限问题

进入主目录,将runtime目录设置为777,注意-R一定是大写的R,不然无法执行

chmod -R 777 runtime/

然后将public目录设置为755,如果运行有问题,则将其设置为755

chmod -R 755 public/

没有意外情况出现的话,tp5可以正常运行

如果还运行不了,将整个工程设置为777,然后重复上述两步

数据库配置

tp5支持解析带端口号的数据库地址

根据实际情况配置,单一库或者主从库

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

return [
    // 数据库类型
    'type'            => 'mysql',
    // 服务器地址
    'hostname'        => 'bj-cdb-nivnaury.sql.tencentcdb.com:60991',
    // 数据库名
    'database'        => 'lianmai',
    // 用户名
    'username'        => 'username',
    // 密码
    'password'        => 'password',
    // 端口
    'hostport'        => '60991',
    // 连接dsn
    'dsn'             => '',
    // 数据库连接参数
    'params'          => [],
    // 数据库编码默认采用utf8
    'charset'         => 'utf8',
    // 数据库表前缀
    'prefix'          => '',
    // 数据库调试模式
    'debug'           => true,
    // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
    'deploy'          => 0,
    // 数据库读写是否分离 主从式有效
    'rw_separate'     => true,
    // 读写分离后 主服务器数量
    'master_num'      => 1,
    // 指定从服务器序号
    'slave_no'        => '',
    // 自动读取主库数据
    'read_master'     => false,
    // 是否严格检查字段是否存在
    'fields_strict'   => true,
    // 数据集返回类型
    'resultset_type'  => 'array',
    // 自动写入时间戳字段
    'auto_timestamp'  => false,
    // 时间字段取出后的默认时间格式
    'datetime_format' => 'Y-m-d H:i:s',
    // 是否需要进行SQL性能分析
    'sql_explain'     => false,
    //'unix_socket' => '/var/run/mysqld/mysqld.sock'
];

数据迁移工具Migration

https://www.cnblogs.com/YC-L/p/12635731.html

跨域处理

在应用生命周期的开头注册下面的跨域类

use think\Response;
 
class CORS
{
    public function appInit(&$params)
    {
        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();
        }
    }
}

tp5.0应用生命周期

tags.php

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

// 应用行为扩展定义文件
return [
    // 应用初始化
    'app_init'     => [
        'app\\api\\behavior\\CORS'
    ],
    // 应用开始
    'app_begin'    => [],
    // 模块初始化
    'module_init'  => [],
    // 操作开始执行
    'action_begin' => [],
    // 视图内容过滤
    'view_filter'  => [],
    // 日志写入
    'log_write'    => [],
    // 应用结束
    'app_end'      => [],
];

Jwt的使用

github地址:https://github.com/lcobucci/jwt

composer安装

composer require lcobucci/jwt

然后写令牌

<?php
namespace app\admin\token;

use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\ValidationData;

class Token
{    
    // 生成jwt
    public static function token($uid = '', $user_name = ''){        

            $signer = new Sha256();

            $token = (new Builder())->setIssuer('https://sqadmin.dao-tech.com')
                ->setAudience('https://sqadmin.dao-tech.com')
                ->setId($uid . $user_name, true) //自定义标识
                ->setIssuedAt(time()) 
                ->setExpiration(time() + (86400 * 30)) //token有效期时长
                ->set('uid', $uid)
                ->sign($signer, 'llwhappyeveryday')
                ->getToken();

            return (String) $token;     
     }        

    // 验证jwt
    public static function check($token, $uid, $user_name) 
    {
        $token = (new Parser())->parse((String) $token);

        $signer =  new Sha256();

        if (!$token->verify($signer, 'llwhappyeveryday')) {
            return false; //签名不正确
        }

        $validationData = new ValidationData();

        $validationData->setIssuer('https://sqadmin.dao-tech.com');
        $validationData->setAudience('https://sqadmin.dao-tech.com');
        $validationData->setId($uid . $user_name);//自定义标识

        return $token->validate($validationData);
    }
}

应用配置 config.php

常用的配置

  • 应用模式
  • 路由缓存
  • pathinfo配置
  • 分页
  • session和cookie
  • 自定义的全局变量
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

return [
    // +----------------------------------------------------------------------
    // | 应用设置
    // +----------------------------------------------------------------------

    // 应用调试模式
    'app_debug'              => true,
    // 应用Trace
    'app_trace'              => false,
    // 应用模式状态
    'app_status'             => '',
    // 是否支持多模块
    'app_multi_module'       => true,
    // 入口自动绑定模块
    'auto_bind_module'       => false,
    // 注册的根命名空间
    'root_namespace'         => [],
    // 扩展函数文件
    'extra_file_list'        => [THINK_PATH . 'helper' . EXT],
    // 默认输出类型
    'default_return_type'    => 'html',
    // 默认AJAX 数据返回格式,可选json xml ...
    'default_ajax_return'    => 'json',
    // 默认JSONP格式返回的处理方法
    'default_jsonp_handler'  => 'jsonpReturn',
    // 默认JSONP处理方法
    'var_jsonp_handler'      => 'callback',
    // 默认时区
    'default_timezone'       => 'PRC',
    // 是否开启多语言
    'lang_switch_on'         => false,
    // 默认全局过滤方法 用逗号分隔多个
    'default_filter'         => '',
    // 默认语言
    'default_lang'           => 'zh-cn',
    // 应用类库后缀
    'class_suffix'           => false,
    // 控制器类后缀
    'controller_suffix'      => false,

    // +----------------------------------------------------------------------
    // | 模块设置
    // +----------------------------------------------------------------------

    // 默认模块名
    'default_module'         => 'index',
    // 禁止访问模块
    'deny_module_list'       => ['common'],
    // 默认控制器名
    'default_controller'     => 'Index',
    // 默认操作名
    'default_action'         => 'index',
    // 默认验证器
    'default_validate'       => '',
    // 默认的空控制器名
    'empty_controller'       => 'Error',
    // 操作方法后缀
    'action_suffix'          => '',
    // 自动搜索控制器
    'controller_auto_search' => false,

    // +----------------------------------------------------------------------
    // | URL设置
    // +----------------------------------------------------------------------

    // PATHINFO变量名 用于兼容模式
    'var_pathinfo'           => 's',
    // 兼容PATH_INFO获取
    'pathinfo_fetch'         => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
    // pathinfo分隔符
    'pathinfo_depr'          => '/',
    // URL伪静态后缀
    'url_html_suffix'        => 'html|json|xml',
    // URL普通方式参数 用于自动生成
    'url_common_param'       => false,
    // URL参数方式 0 按名称成对解析 1 按顺序解析
    'url_param_type'         => 0,
    // 是否开启路由
    'url_route_on'           => true,
    // 路由使用完整匹配
    'route_complete_match'   => false,
    // 路由配置文件(支持配置多个)
    'route_config_file'      => ['route'],
    // 是否开启路由解析缓存
    'route_check_cache'      => false,
    // 是否强制使用路由
    'url_route_must'         => true,
    // 域名部署
    'url_domain_deploy'      => false,
    // 域名根,如thinkphp.cn
    'url_domain_root'        => '',
    // 是否自动转换URL中的控制器和操作名
    'url_convert'            => true,
    // 默认的访问控制器层
    'url_controller_layer'   => 'controller',
    // 表单请求类型伪装变量
    'var_method'             => '_method',
    // 表单ajax伪装变量
    'var_ajax'               => '_ajax',
    // 表单pjax伪装变量
    'var_pjax'               => '_pjax',
    // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
    'request_cache'          => false,
    // 请求缓存有效期
    'request_cache_expire'   => null,
    // 全局请求缓存排除规则
    'request_cache_except'   => [],

    // +----------------------------------------------------------------------
    // | 模板设置
    // +----------------------------------------------------------------------

    'template'               => [
        // 模板引擎类型 支持 php think 支持扩展
        'type'         => 'Think',
        // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写
        'auto_rule'    => 1,
        // 模板路径
        'view_path'    => '',
        // 模板后缀
        'view_suffix'  => 'html',
        // 模板文件名分隔符
        'view_depr'    => DS,
        // 模板引擎普通标签开始标记
        'tpl_begin'    => '{',
        // 模板引擎普通标签结束标记
        'tpl_end'      => '}',
        // 标签库标签开始标记
        'taglib_begin' => '{',
        // 标签库标签结束标记
        'taglib_end'   => '}',
    ],

    // 视图输出字符串内容替换
    'view_replace_str'       => [],
    // 默认跳转页面对应的模板文件
    'dispatch_success_tmpl'  => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',
    'dispatch_error_tmpl'    => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',

    // +----------------------------------------------------------------------
    // | 异常及错误设置
    // +----------------------------------------------------------------------

    // 异常页面的模板文件
    'exception_tmpl'         => THINK_PATH . 'tpl' . DS . 'think_exception.tpl',

    // 错误显示信息,非调试模式有效
    'error_message'          => '页面错误!请稍后再试~',
    // 显示错误信息
    'show_error_msg'         => false,
    // 异常处理handle类 留空使用 \think\exception\Handle
    'exception_handle'       => '',

    // +----------------------------------------------------------------------
    // | 日志设置
    // +----------------------------------------------------------------------

    'log'                    => [
        // 日志记录方式,内置 file socket 支持扩展
        'type'  => 'File',
        // 日志保存目录
        'path'  => LOG_PATH,
        // 日志记录级别
        'level' => [],
    ],

    // +----------------------------------------------------------------------
    // | Trace设置 开启 app_trace 后 有效
    // +----------------------------------------------------------------------
    'trace'                  => [
        // 内置Html Console 支持扩展
        'type' => 'Html',
    ],

    // +----------------------------------------------------------------------
    // | 缓存设置
    // +----------------------------------------------------------------------

    'cache'                  => [
        // 驱动方式
        'type'   => 'File',
        // 缓存保存目录
        'path'   => CACHE_PATH,
        // 缓存前缀
        'prefix' => '',
        // 缓存有效期 0表示永久缓存
        'expire' => 0,
    ],

    // +----------------------------------------------------------------------
    // | 会话设置
    // +----------------------------------------------------------------------

    'session'                => [
        'id'             => '',
        // SESSION_ID的提交变量,解决flash上传跨域
        'var_session_id' => '',
        // SESSION 前缀
        'prefix'         => 'think',
        // 驱动方式 支持redis memcache memcached
        'type'           => '',
        // 是否自动开启 SESSION
        'auto_start'     => true,
    ],

    // +----------------------------------------------------------------------
    // | Cookie设置
    // +----------------------------------------------------------------------
    'cookie'                 => [
        // cookie 名称前缀
        'prefix'    => '',
        // cookie 保存时间
        'expire'    => 0,
        // cookie 保存路径
        'path'      => '/',
        // cookie 有效域名
        'domain'    => '',
        //  cookie 启用安全传输
        'secure'    => false,
        // httponly设置
        'httponly'  => '',
        // 是否使用 setcookie
        'setcookie' => true,
    ],

    //分页配置
    'paginate'               => [
        'type'      => 'bootstrap',
        'var_page'  => 'page',
        'list_rows' => 15,
    ],
    // 小程序信息設置
    'wxapp' => [
        'appid' =>'',
        'appsecret'=>''
    ],
    'aliyun_access'=>[
        'accessKeyID'=>'',
        'accessKeySecret'=>''
    ]
];

路由配置

定义路由

use think\Route;
// 注册路由到index模块的News控制器的read操作
Route::rule('new/:id','index/News/read');

带提交方式

Route::rule('new/:id','News/update','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::rule('new/:id','News/read','GET|POST');

使用数组批量添加路由

Route::rule([
    'new/:id'  =>  'News/read',
    'blog/:id' =>  ['Blog/update',['ext'=>'shtml'],['id'=>'\d{4}']],
    ...
],'','GET',['ext'=>'html'],['id'=>'\d+']);

变量规则

全局变量

// 设置name变量规则(采用正则定义)
Route::pattern('name','\w+');
// 支持批量添加
Route::pattern([
    'name'  =>  '\w+',
    'id'    =>  '\d+',
]);

局部变量

// 定义GET请求路由规则 并设置name变量规则
Route::get('new/:name','News/read',[],['name'=>'\w+']);

完整url规则

// 定义GET请求路由规则 并设置完整URL变量规则
Route::get('new/:id','News/read',[],['__url__'=>'new\/\w+$']);

路由参数

method 请求类型检测,支持多个请求类型
ext URL后缀检测,支持匹配多个后缀
deny_ext URL禁止后缀检测,支持匹配多个后缀
https 检测是否https请求
domain 域名检测
before_behavior 前置行为(检测)
after_behavior 后置行为(执行)
callback 自定义检测方法
merge_extra_vars 合并额外参数
bind_model 绑定模型(V5.0.1+
cache 请求缓存(V5.0.1+
param_depr 路由参数分隔符(V5.0.2+
ajax Ajax检测(V5.0.2+
pjax Pjax检测(V5.0.2+

路由地址定义

方式1:路由到模块/控制器 '[模块/控制器/操作]?额外参数1=值1&额外参数2=值2...'
方式2:路由到重定向地址 '外部地址'(默认301重定向) 或者 ['外部地址','重定向代码']
方式3:路由到控制器的方法 '@[模块/控制器/]操作'
方式4:路由到类的方法 '\完整的命名空间类::静态方法' 或者 '\完整的命名空间类@动态方法'
方式5:路由到闭包函数 闭包函数定义(支持参数传入)

可以用路由到控制器方法,这种不用二次解析路由

'blog/:id'=>'@index/blog/read'

系统会直接执行

Loader::action('index/blog/read');

路由到类方法

'blog/:id'=>'\app\index\service\Blog@read'

重定向地址使用动态变量即可

'blog/:id'=>'http://blog.thinkphp.cn/read/:id'

路由别名

// user 别名路由到 index/User 控制器
Route::alias('user','index/User');

在route.php种定义

return [
    '__alias__' =>  [
        'user'  =>  'index/User',
    ],
];

路由别名可以指向任意一个有效的路由地址,例如下面指向一个类

// user 路由别名指向 User控制器类
Route::alias('user','\app\index\controller\User');

路由别名设置路由条件

// user 别名路由到 index/user 控制器
Route::alias('user','index/user',['ext'=>'html']);

在route.php中配置

return [
    '__alias__' =>  [
        'user'  =>  ['index/user',['ext'=>'html']],
    ],
];

操作方法黑白名单

路由别名的操作方法支持白名单或者黑名单机制,例如:

// user 别名路由到 index/user 控制器
Route::alias('user','index/user',[
    'ext'=>'html''allow'=>'index,read,edit,delete',
]);

或者使用黑名单机制

// user 别名路由到 index/user 控制器
Route::alias('user','index/user',[
    'ext'=>'html''except'=>'save,delete',
]);

并且支持设置操作方法的请求类型,例如:

// user 别名路由到 index/user 控制器
Route::alias('user','index/user',[
    'ext'=>'html''allow'=>'index,save,delete',
    'method'=>['index'=>'GET','save'=>'POST','delete'=>'DELETE'],
]);

路由分组

'blog/:id'   => ['Blog/read', ['method' => 'get'], ['id' => '\d+']],
'blog/:name' => ['Blog/read', ['method' => 'post']],

可以合并到一个blog分组

'[blog]'     => [
    ':id'   => ['Blog/read', ['method' => 'get'], ['id' => '\d+']],
    ':name' => ['Blog/read', ['method' => 'post']],
],

可以使用Group类的group方法

Route::group('blog',[
    ':id'   => ['Blog/read', ['method' => 'get'], ['id' => '\d+']],
    ':name' => ['Blog/read', ['method' => 'post']],
]);

路由分组支持嵌套

Route::group(['method'=>'get','ext'=>'html'],function(){
    Route::group('blog',function(){
        Route::any('blog/:id','blog/read',[],['id'=>'\d+']);
        Route::any('blog/:name','blog/read',[],['name'=>'\w+']);
    }
});

全部miss路由

return [
    'new/:id'   => 'News/read',
    'blog/:id'  => ['Blog/update',['method' => 'post|put'], ['id' => '\d+']],
    '__miss__'  => 'public/miss',
];

也可以使用miss方法

Route::miss('public/miss');

分组miss路由

return [
    '[blog]' =>  [
        'edit/:id'  => ['Blog/edit',['method' => 'get'], ['id' => '\d+']],
        ':id'       => ['Blog/read',['method' => 'get'], ['id' => '\d+']],
        '__miss__'  => 'blog/miss',
    ],
    'new/:id'   => 'News/read',
    '__miss__'  => 'public/miss',
];

在group方法中嵌套miss方法

Route::group('blog',function(){
    Route::rule(':id','blog/read',[],['id'=>'\d+']);
    Route::rule(':name','blog/read',[],['name'=>'\w+']);
    Route::miss('blog/miss');
},['method'=>'get','ext'=>'html']);

路由闭包函数

Route::get('hello/:name',function($name){ 
    return 'Hello,'.$name;
});
posted @ 2021-01-23 09:15  BigBender  阅读(1068)  评论(0编辑  收藏  举报