thinkphp5.0 使用小技巧总结

1、在application的目录下建立common文件夹,那么在tp中有进行处理过,是不能被访问的,那么在common文件夹下,可以建立些公用的方法或者基类

 2、系统提供了专门的标签来简化上面的导入

{load href="/static/js/common.js" /}
{load href="/static/css/style.css" /}
<!--也可以同时引入多个-->
{load href="/static/js/common.js,/static/css/style.css" /}
<!--系统还提供了两个标签别名js和css 用法和load一致,例如:-->
{js href="/static/js/common.js" /}
{css href="/static/css/style.css" /}

 3、在使用{:url('index/index')}的时候可以不填写模块,因为系统在哪个模块下面,那么路由会被自动定位到对应的模块下面

 4、thinkphp5中,使用validate进行较验的时候,如果需要知道多个较验证效果,那么可以使用batch这个接口如下:

public function add() {
    $param = request()->post();
    $v = validate('AdminUser')->scene('add');
    if(!$v->batch()->check($param)) {
        dump($v->getError());
    } else {
        dump('ok');
    }
}

 5、thinkphp5 提供了一个抛出异常的方法exception('...')来抛出异常

 6、自定义配置,可以在application下新建一个目录extra,再在下面新建配置文件,如:captcha.php,那么访问需要用config('captcha.width')的方式进行访问。

 7、ajax请求可以用controller里面自动定义的方法$this->result()进行返回。如果需要自定义的情况,那么可以自动return [...]的方式即可。

 8、上传文件进行检测时可以采用以下方法

$file = request()->file('file');
$file->check([
    'type' => 'image/jpg,image/png,image/jpeg',
    'size' => 2097152,
    'ext' => 'png,jpg'
]);
halt($file->getError());
//注意以下逗号之间是不能的空隔的

也可以使用validate

$file = request()->file('file');
$res = $file->validate([
    'type' => 'image/jpg,image/png,image/jpeg',
    'ext' => 'png,jpg',
    'size' => 'fileSize:2097152'
]);
dump($res->check());
halt($res->getError());

也可以使用单独的方法,如下

$file = request()->file('file');
$res = $file->checkMime(['image/png', 'image/jpeg','image/png']);
dump($res);

 9、文件上传示例

public function uploadData() {
    $file = request()->file('file');
    $rule = $file->checkMime(['image/jpeg', 'image/jpg', 'image/png']);
    if($rule) {
        $res = $file->move('upload');
        $this->result(['path' => $res->getPathname()], 200, '上传成功');
    } else {
        $this->result([], 500, '类型有误');
    }
}

 10、文件上传至七牛云方法

// 引入鉴权类
use QiniuAuth;
// 引入上传类
use QiniuStorageUploadManager;
// 需要填写你的 Access Key 和 Secret Key
$accessKey ="your accessKey";
$secretKey = "your secretKey"
$bucket = "your bucket name";
// 构建鉴权对象
$auth = new Auth($accessKey, $secretKey);
// 生成上传 Token
$token = $auth->uploadToken($bucket);
// 要上传文件的本地路径
$filePath = './php-logo.png';
// 上传到七牛后保存的文件名
$key = 'my-php-logo.png';
// 初始化 UploadManager 对象并进行文件的上传。
$uploadMgr = new UploadManager();
// 调用 UploadManager 的 putFile 方法进行文件的上传。
list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath);
echo "
====> putFile result: 
";
if ($err !== null) {
    var_dump($err);
} else {
    var_dump($ret);
}

 封装七牛云的sdk

<?php
namespace appcommonutils;
use QiniuAuth;
use QiniuStorageUploadManager;

class Upload{
    public static function imgUpload($name) {
        $file = request()->file($name)->getInfo();
        if(!empty($file)) {
            $key = self::getNewName(pathinfo($file['name'], PATHINFO_EXTENSION));
            $upload = new UploadManager();
            list($ret, $err) = $upload->putFile(self::getToken(), $key, $file['tmp_name']);
            if($err !== null) {
                return null;
            } else {
                return $ret['key'];
            }
        }
        return null;
    }

    /**获取 token
     * @return string
     */
    private static function getToken() {
        $auto = new Auth(config('qiniu.ak'), config('qiniu.sk'));
        return $auto->uploadToken(config('qiniu.bucket'));
    }

    /**生成新的名字
     * @param $ext
     * @return string
     */
    private static function getNewName($ext) {
        return date('Ymd').uniqId(config('qiniu.prefix')).'.'.$ext;
    }

}

 注意:如果需要下载七牛云上的资源可以使用

http://<domain>/<key>?attname=<file_name>   //如  http://www.baidu.com/abc.jpg?attname=a.jpg

具体可以参考   https://developer.qiniu.com/kodo/manual/1659/download-setting

11、在使用try{}catch(Exception $e) {}当中尽可能的不用$this->result();但这个可以在外面使用或者在异常处使用,否则容易出错如下

public function submitData() {
    $data = request()->post();
    $v = validate('News');
    if(!$v->check($data)) {
        $this->result([], 300, $v->getError());
    } else {
        try{
            $data['create_time'] = $data['update_time'] = request()->server('REQUEST_TIME');
            model('News')->allowField(true)->save($data);
        }catch(Exception $e) {
            $this->result(['msg' => $e->getMessage(), 'code' => $e->getCode()], 300, $e->getMessage());
        }
        $this->result([], 200, '操作成功');
    }
}

 12、在application下面的common.php中定义方法,那么在tp类中是可以正常调用到的

<?php
// 应用公共文件
function getMsg() {
    return 'are you ok???';
}

 13、在application下面有一个json()方法,可以返回前端ajax请求的状态码(status)以及对应的数据data,如下:

public function index() {
    return json([
        'name' => 'abc',
        'age' => 30,
    ], 201);
}

 14、thinkphp5不可预知的内部异常的处理解决办法

方法一:更改错误信息的渲染方式(主要是针对系统内容的错误)

  a、定义一个错误处理类,并且继承TP5里的handle方法,重写里面的render方法,如下:

<?php
namespace appcommonutils;
use Exception;
use thinkexceptionHandle;

class ApiExceptionHandle extends Handle{
    private $code = 500;
    public function render(Exception $e) {
        $data =  [
            'code' => 1,
            'msg' => config('app_debug')? $e->getMessage(): '服务器错误',
            'data' => []
        ];
        return json($data, $this->code);
    }
}

  b、在application中的config.php中配置异常的处理方法,如下

 方法二、手动抛出错误的(主要针对开发过程中,抛出的异常,前提是建立在方法一上,进行修改)

  a、添加一个手动抛出异常的类

<?php
namespace appcommonutils;
use thinkException;
use Throwable;
class ApiException extends Exception {
    public $a_code;
    public $a_message;
    public $a_data;
    public $a_status;

    public function __construct($message = "", $code = 0, Throwable $previous = null, $data = [], $status = 500)
    {
        parent::__construct($message, $code, $previous);
        $this->a_code = $code;                          //自定义的里面的code
        $this->a_message = $message;                    //自定义的data里的message
        $this->a_data = $data;                          //自定义的data数据
        $this->a_status = $status;                      //自定义的status状态码
    }
}

  b、对原有的ApiExceptionHandle 类进行修改

<?php
namespace appcommonutils;
use Exception;
use thinkexceptionHandle;

class ApiExceptionHandle extends Handle{
    private $code = 500;
    public function render(Exception $e) {
        if(!config('app_debug')) {          //是否开启debug
            if($e instanceof ApiException) {       //如果是自定义的抛出异常,那么就使用自定义的status以及其他参数
                $this->code = $e->a_status;        //覆盖原有的$code
                $data = ['code' => $e->a_code, 'msg' => $e->a_message, 'data' => $e->a_data];   //调用ApiException中定义的参数
            } else {
                $data =  ['code' => 1, 'msg' => '服务器错误', 'data' => []];
            }
            return json($data, $this->code);       //返回AJAX请求
        }
        return parent::render($e);
    }
}

  c、可以在application下的common.php中封装一个调用的方法(例子无)以方便调用

  d、调用例子如下:

class Test extends Controller
{
    public function index() {
        throw new ApiException('are you ok???', 300, null, ['a' => 'aaaa'],404);
    }

 15、多级控制器的使用以及路由的配置

namespace appindexcontrollerone;

use thinkController;

class Blog extends Controller
{
    public function index()
    {
        return $this->fetch();
    }
    
    public function add()
    {
        return $this->fetch();
    }
    
    public function edit($id)
    {
        return $this->fetch();
    }
}
//访问地址如下
http://serverName/index.php/index/one.blog/index
//可以进行如下的路由配置
	hinkRoute::get('blog/add','index/one.Blog/add');

 16、对于一些不能通过composer来安装的sdk,那么可以安装到thinkphp5下的extend目录下,做为一个扩展使用

注意:在安装的时候,要填对namespace,否则会访问不到相关的类

a、如 在extend下的一个lib目录安装一个test 类,那么它的namespace路径则需要写作 namespace lib,  如果在lib下还有一个文件夹a 下面才是test,   那么namespace为: namespace liba;

b、安装sdk的时候注意如果没有命名空间的话,那么需要添加上对应的命名空间

  17、在做接口的时候,较验的时候,model或其他非controller模块,尽可能返回完整的数据信息,这样以避免controller再去适配ajax的返回json数据,如下示例(以下可进行进一步封装)

/**发送短信
 * @param $phone
 * @return array|bool
 * @throws Exception
 */
public static function sendLoginMsg($phone) {
    $code = mt_rand(1000, 9999);
    $res = self::checkStatus($phone);
    if($res === true) {
        $res = SendMsg::getInstance()->send($phone, [$code, config('sms.expire')/60]);
        if($res['res'] === 0) {
            self::saveStatus($phone, $code);
            return ['code' => 0, 'msg' => '发送成功', 'data' => []];    //可以将数据封装成一个方法
        } else {
            Log::write('发送信息失败'.json_encode($res));
            return ['code' => 1, 'msg' => $res['msg'], 'data' => []];
        }
    }
    return $res;
}
原文地址:https://www.cnblogs.com/rickyctbu/p/11623762.html