• 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 thinkResponse;
     
    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 appadmin	oken;
    
    use LcobucciJWTBuilder;
    use LcobucciJWTSignerHmacSha256;
    use LcobucciJWTParser;
    use LcobucciJWTValidationData;
    
    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类 留空使用 	hinkexceptionHandle
        '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 thinkRoute;
    // 注册路由到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'=>'appindexserviceBlog@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','appindexcontrollerUser');

    路由别名设置路由条件

    // 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;
    });
    论读书
    睁开眼,书在面前
    闭上眼,书在心里
  • 相关阅读:
    绘图与滤镜全面解析
    排序算法——快速排序
    IOS QuartzCore核心动画框架
    const 笔记
    operation 多线程
    指针 总结
    问题 H: 老管家的忠诚(线段树)
    问题 H: 老管家的忠诚(线段树)
    Python——numpy(python programming)
    Python——numpy(python programming)
  • 原文地址:https://www.cnblogs.com/YC-L/p/14316511.html
Copyright © 2020-2023  润新知