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 Qiniu\Auth; // 引入上传类 use Qiniu\Storage\UploadManager; // 需要填写你的 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 "\n====> putFile result: \n"; if ($err !== null) { var_dump($err); } else { var_dump($ret); }
封装七牛云的sdk
<?php namespace app\common\utils; use Qiniu\Auth; use Qiniu\Storage\UploadManager; 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 app\common\utils; use Exception; use think\exception\Handle; 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 app\common\utils; use think\Exception; 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 app\common\utils; use Exception; use think\exception\Handle; 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 app\index\controller\one; use think\Controller; 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 //可以进行如下的路由配置 \think\Route::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 lib\a;
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; }