本笔记内容是基于ThinkPHP5.0.7进行实践。

1.路由书写规则route.php

需要声明:默认tp采用path_info模式的实现路由,默认是:’http://servername/模块/控制器/方法’。但可以通过修改route.php使用路由规则来实现url寻址。默认情况下tp采用的是混合路由规则,即上述两个路由方式共存,但针对不同方法而言,即同一个方法,如果使用两种不同的路由定义方法,路由规则的优先级大于path_info。也可以通过设置严格路由模式,禁止使用path_info使系统较为统一。接下来讲述的是配置路由规则:

默认:以配置形式返回

return ['__pattern__' => ['name' => '\w+',],'[hello]'     => [':id'   => ['index/hello', ['method' => 'get'], ['id' => '\d+']],':name' => ['index/hello', ['method' => 'post']],],];

可以修改为如下:(把文件内容清空,重新编写如下)

//先引入route类
use think/Route;//编写路由规则
//Route::rule('路由表达式','路由地址','请求类型','路由参数(数组)','变量规则(数
组)');
//Route::rule('hello', 'simple/Test/hello','GET|POST',['https'=>false]);
//Route::get('hello', 'simple/Test/hello');
//Route::post('hello', 'simple/Test/hello');
//Route::any();
//传递参数
Route::get('hello/:id', 'simple/Test/hello');

上面提供多种形式的路由编写规则,可根据需要进行选择使用。

2.控制器获取前端传来参数方式

namespace app/simple/controller;
use think\Request;class Test
{public function hello($id, $name){echo $id;echo "|";echo $name;
//        return "hello,here is test/hello";}public function test(){$all = Request::instance()->param();var_dump($all);
//        $all = Request::instance()->route();//获取url参数
//        $all = Request::instance()->get();//获取?后面的参数
//        $all = Request::instance()->post();//获取post参数
//        $id = Request::instance()->param('id');
//        $name = Request::instance()->param('name');
//        $age = Request::instance()->param('age');//使用助手函数$all = input('param.');//获取所有,获取单个param.name//$all = input('get.age');}//使用依赖注入方式获取参数变量public function test2(Request $request){$all = $request->param();}
}

上述代码提供了三种的获取参数的方式:静态方法获取、助手函数获取、依赖注入方式获取。

3.信息校验

方式之一:独立验证

use think/Validate; public function getBanner($id) {$data = ['name' => 'vender','email' => 'vender@qq.com',];$validate = new Validate(['name' => 'require|max:10','email' => 'email',]);$result = $validate->batch()->check($data);var_dump($validate->getError());
}

方式二:验证器

在模块目录或者application目录下创建一个validate的文件夹,在文件夹下创建验证器类:

namespace app\api\validate;use think\Validate;class TestValidate extends Validate
{protected $rule = ['name' => 'require|max:10','email' => 'email'];
}

调用方式:

//use app\api\validate\TestValidate;用于直接new对象使用public function getBanner($id){$data = ['name' => 'vender13456879','email' => 'vender@qq.com',];//需要引入类//$validate = new TestValidate();//直接使用助手函数进行创建对象$validate = validate('TestValidate');$result = $validate->batch()->check($data);var_dump($validate->getError());
}

官方也建议使用验证器进行验证,条理更加清晰,封装性更好。

当需要验证的数据,官方文档没有给出校验规则时,可以自定义校验规则,创建方法如上面创建,只需添加一个protected校验方法如下:

//判断是否为正整数
protected function isPostiveInteger($value, $rule = '', $data = '', $field = '') {if(is_numeric($value) && is_int($value + 0) && ($value + 0) > 0) {return true;} else {return $field . '必须为正整数';}
}

使用方法:(完整代码示例)

namespace app\api\validate;use think\Validate;class IDMustBePostiveInt extends Validate
{protected $rule = ['id' => 'require|isPostiveInteger'];protected function isPostiveInteger($value, $rule = '', $data = '', $field = '') {if(is_numeric($value) && is_int($value + 0) && ($value + 0) > 0) {return true;} else {return $field . '必须为正整数';}}
}

如上述代码所示,直接在$rule中使用自定义的方法即可。

尽管采用了验证器,但每次调用验证器都需要重复上面的调用代码,会产生很多的代码冗余,因此,抽象出一个验证层很有必要。实现方法如下:在validate类新建一个验证基类BaseValidate.php,代码如下:

namespace app\api\validate;use think\Exception;
use think\Request;
use think\Validate;class BaseValidate extends Validate
{public function goCheck(){//获取http传入的参数变量//对参数进行验证$request = Request::instance();$params = $request->param();$result = $this->check($params);if(!$result) {$error = $this->getError();throw new Exception($error);} else {return true;}}
}

然后,让各个校验类继承该基类:

namespace app\api\validate;use think\Validate;class IDMustBePostiveInt extends BaseValidate
{protected $rule = ['id' => 'require|isPostiveInteger'];protected function isPostiveInteger($value, $rule = '', $data = '', $field = '') {if(is_numeric($value) && is_int($value + 0) && ($value + 0) > 0) {return true;} else {return $field . '必须为正整数';}}
}

现在的调用代码精简如下:

namespace app\api\controller\v1;use app\api\validate\IDMustBePostiveInt;class Banner
{/*** 获取banner* @url /banner/:id* @param $id banner的id号*/public function getBanner($id){(new IDMustBePostiveInt())->goCheck();echo 1;}
}

通过上面方法,代码复用性增强且精简。

4、异常处理

默认tp框架提供异常处理,我们只需要try-catch进行异常抛出和捕获即可,但是,当我们需要根据自己的实际需要给出响应的异常信息时,我们需要自定义自己的异常类,并进行异常抛出并捕获。

系统异常大可分为两类:用户操作异常和系统内部代码异常。前者不需要返回用户具体代码的错误信息,只需返回合适的提示信息即可;而后者信息一般不会直接返回给客户端,因为返回给客户端也没有用,人家不会给你处理,此时我们只需要返回客户端,告诉他我们服务端内部出错即可。因此,自定义异常处理类很有必要。

tp框架自定义异常处理类步骤如下:

首先,自定义的一个异常基类:BaseException.php

namespace app\lib\exception;use think\Exception;//让基类继承tp的异常类,并定义自己的一些异常编码及提示信息
class BaseException extends Exception
{//http状态码public $code = 400;//错误具体信息public $msg = '参数错误';//自定义的错误码public $errorCode = 10000;
}

其次,定义一个某个场景下所出现的异常。例如,系统需要通过id找到对应的数据库记录,当记录存在时,我们认为这是一个异常,并抛出(不考究举例是否合理,仅作假设)。接下来,我们需要定义这个异常类:BannerMissException.php

<?php
namespace app\lib\exception;use app\lib\exception\BaseException;//让自定义的异常类继承基类,并重写父类的异常编码及提示信息
class BannerMissException extends BaseException
{public $code = 404;public $msg = "请求Banner不存在";public $errorCode = 40000;
}

最后,定义自己的异常处理类ExceptionHandle.php,目的是让抛出的异常直接经过自己定义的异常处理方法,替代tp默认的的处理方法,从而实现自定义异常处理效果。代码如下:

<?php
namespace app\lib\exception;use think\exception\Handle;
use think\Request;
use Exception;  //注意这里使用的不是think\Exception,与继承的Handle类保持一致
use app\lib\exception\BaseException;//继承tp的异常处理基类Handle,并覆盖render异常处理方法
class ExceptionHandle extends Handle
{protected $code;protected $msg;protected $errorCode;public function render(Exception $e){//判断抛出的异常是否为自定义的异常if($e instanceof BaseException) {//如果是自定义的异常$this->code = $e->code;$this->msg = $e->msg;$this->errorCode = $e->errorCode;} else {$this->code = 500;$this->msg = "服务器内部错误123";$this->errorCode = 999;}$request = Request::instance();$result = ['msg' => $this->msg,'error_code' => $this->errorCode,'request_url' => $request->url(),];return json($result, $this->code);}
}

调用方法:直接在出现异常的地方抛出自定义的异常类即可被自定义的处理类捕获并处理。

<?php
namespace app\api\controller\v1;use app\api\validate\IDMustBePostiveInt;
use app\api\model\Banner as BannerModel;
use app\lib\exception\BannerMissException;class Banner
{/*** 获取banner* @url /banner/:id* @param $id banner的id号* @return banner* @throws BannerMissException*/public function getBanner($id){//校验id是否为正整数(new IDMustBePostiveInt())->goCheck();$banner = BannerModel::getBannerByID($id);if(!$banner) {throw new BannerMissException();}
//        return $banner;}
}

测试方法,在上述代码BannerModel::getBannerByID(),让其返回null即可显示自定义的异常。

5、写入日志

tp框架默认会对所有异常进行自动写入日志,但是有很多异常信息我们实际上并不需要记录,这样导致空间的浪费,因此我们有必要进行自定义的日志写入。

首先,关闭tp的自动写入日志功能,编辑config.php文件:把File改成test即可

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

然后再需要写日志的地方进行日志写入,此处省略日志文件路径的配置。我们一般记录系统内部错误异常日志即可。因此,我们可以在此前的全局异常处理类中进行日志写入,代码如下:

<?php
namespace app\lib\exception;use think\exception\Handle;
use think\Log;
use think\Request;
use Exception;
use app\lib\exception\BaseException;class ExceptionHandle extends Handle
{protected $code;protected $msg;protected $errorCode;public function render(Exception $e){if($e instanceof BaseException) {//如果是自定义的异常$this->code = $e->code;$this->msg = $e->msg;$this->errorCode = $e->errorCode;} else {$this->code = 500;$this->msg = "服务器内部错误";$this->errorCode = 999;//调用日志写入方法,写入异常信息$this->recordErrorLog($e);}$request = Request::instance();$result = ['msg' => $this->msg,'error_code' => $this->errorCode,'request_url' => $request->url(),];return json($result, $this->code);}//自定义日志写入方法,引入think/Log类private function recordErrorLog(Exception $e) {//对日志进行初始化操作,等同于config.php中的配置效果Log::init(['type' => 'File','path' => LOG_PATH,'level' => ['error']]);//仅仅记录error及其以上级别的异常Log::record($e->getMessage(), 'error');}
}

tp默认日志保存路径为:runtime/log/日期。linux下需要提供文件写入权限。

6、数据库操作:

首先需要简单理解模型的概念。模型不等同于model,而是model(对象)+logic(逻辑)。模型不仅仅用于操作数据库,而应该包含一些逻辑处理。

tp操作数据库可以采用三种方法:原生sql、查询构建器、ORM模型关系映射。这些操作都是在model类中实现和使用。

方式一:使用原生sql

直接编写sql语句如下:需引入think\Db类

$result = Db::query('select * from banner_item where banner_id = ?',[$id])

方式二:使用查询构建器

直接编写sql语句如下:需引入think\Db类

$result = Db::table('banner_item')->where('banner_id', '=', $id)->select();

注意:
1.使用查询构建器find()返回一维数组,即单条记录,select()返回二维数组;

2.分为两部分:辅助方法(链式方法)、执行方法。前者可多个,且无顺序关系;
3.update()、delete()、insert()、find()、select()称为执行方法,前面的称为辅助方法,也叫链式方法;
4.辅助方法一般结构:where(‘字段名’,’表达式’,’查询条件’),且需要执行执行方法才能真正进行数据查询,否则只能返回拼接的sql语句;

查询构建器有三种形式:表达式、数组、闭包。其中闭包实现方式如下:

$result = Db::table('banner_item')->where(function($query) use ($id){$query->where('banner_id','=',$id);
})->select();

如果在链式方法添加fetchsql()方法时,sql不会执行,而是返回SQL语句:

$result = Db::table('banner_item')->fetchsql()->where('banner_id', '=', $id)->select();

方式三:使用模型ORM

使用模型,模型不等于model,可以分成model+service,或者更多。模型的实现需要继承tp的Model类。

//使用模型BannerModel的静态方法,通过id找到对应的记录
$banner = BannerModel::find($id);

表示表与表之间的关联关系

一对多:Banner <- Banneritem

在一的一方model(Banner)添加描述对应关系的方法如下:

public function items()
{return $this->hasMany('BannerItem','banner_id','id');
}

使用:

$banner = BannerModel::with('items')->find($id);//建议使用,调用简洁、逻辑合理

获取的结果自动包含关联的多条Banneritem的相关内容。

一对一:Image <-> Banneritem

在BannerItemModel中添加如下方法代码:

public function img()
{return $this->belongsTo('Image','img_id', 'id');
}

使用:

$banner = BannerModel::with(['items','items.img'])->find($id);

以上代码建议写在模型内部,而不是控制器中,控制器直接调用模型的封装的方法即可,代码更清晰合理。

隐藏字段

有时候,我们需要隐藏查询到的一些记录的字段信息,例如delete_time之类的,常规方法,我们需要将查询出来的记录数据进行重新处理再返回,但实际上,tp的模型为我们提供了封装好的方法,调用如下:

$banner = BannerModel::getBannerByID($id);
$banner->hidden(['delete_time','update_time']);

tp模型类封装了很多的方法,详细可以自行探讨。

Thinkphp基本使用知识相关推荐

  1. ThinkPHP 的一些知识

    1.定义控制器层不一定要继承Controller,但是要输出模板的话,却是必须继承了. 2.通过设置CONTROLLER_LEVEL(默认为1),可以通过子目录把控制器分层存放.(比如 'CONTRO ...

  2. thinkPHP开发基础知识 包括变量神马的

    2019独角兽企业重金招聘Python工程师标准>>> thinkPHP框架开发的应用程序,一般都采用单一入口的方式,下面是在应用首页文件中实现的定义: 1.在首页定义thinkPH ...

  3. ThinkPhp框架基础知识

    ThinkPhp是一个采用MVC框架,免费开源.快捷简单的OOP轻量级PHP框架. MVC分三个部分: Model 模型层:模型层是应用程序的核心,可以是一个实体或一种业务逻辑,在应用程序中有更好的重 ...

  4. php think框架,ThinkPHP框架基础知识

    ThinkPHP是一个PHP开发框架,使用面向对象的开发结构和MVC模式,简称tp框架. 1.框架是一堆代码的集合,里边有变量.函数.类.常量,里边也有许多设计模式MVC.AR数据库.单例等等,框架的 ...

  5. thinkphp API 使用知识

    打开网址   ThinkPHP服务市场 市场入住说明  入驻产品信息 · ThinkPHP应用服务市场入驻申请 · 看云 举例短信接口 短信API文档 接口使用参考这里:短信API服务 · Think ...

  6. thinkphp的增删改查

    ThinkPHP 添加数据 add 方法 ThinkPHP 内置的 add 方法用于向数据表添加数据,相当于 SQL 中的 INSERT INTO 行为. ThinkPHP Insert 添加数据 添 ...

  7. ThinkPHP 入门

    编写:ThinkPHP 文档组 最后更新:20090501 共 40 页 第 2 页 © Copyright 2006~2009 版权所有 http://thinkphp.cn(放在这里,备查,也方便 ...

  8. php 框架的作用,ThinkPHP框架作用

    ThinkPHP是一个开源的PHP框架, 是为了简化企业级应用开发和敏捷WEB应用开发而诞生的.最早诞生于2006年初,原名FCS,2007年元旦正式更名为ThinkPHP,并且遵循Apache2开源 ...

  9. (附源码)php遵义旅游管理系统 毕业设计091801

    遵义旅游管理系统的设计与实现 摘 要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课 ...

最新文章

  1. 隐藏探针显示php版本号,修改版雅黑PHP探针 支持PHP7+(v0.4.7.2)
  2. 企业网络推广下的B站二次上市:致力于造就国内最具活力和创造力的内容社区...
  3. Oracle11gExp导出空表方法
  4. Java打乱牌的算法_Leetcode 384. 打乱数组 (洗牌算法)
  5. python空列表添加_Python列表的简单操作
  6. 蚂蚁金服开放计算架构:下一代金融级计算架构
  7. 腾讯大数据之TDW计算引擎解析——Shuffle
  8. Linux Shell数值比较和字符串比较及相关
  9. mysql增删改查大全_MySQL数据库增删改查SQL语句(2018整理集合大全)
  10. 基于java的企业人事管理系统的设计与实现_人事管理系统如何实现企业薪酬管理升级?...
  11. layabox 学习笔记
  12. Python GUI项目:文件夹管理系统
  13. DeepReID: Deep Filter Pairing Neural Network for Person Re-Identification
  14. python拟合log函数得出公式
  15. U盘无法在磁盘管理器中删除,显示不支持该操作的时候可以用以下的办法,亲测可以解决
  16. 蛋白质二级结构预测Linux,蛋白质稳定性预测工具-Rosetta ddg_monomer
  17. libpqxx 库安装configure: error:Linking a call to libpq failed in C++, even though it succeeded in C.
  18. 扩充计算机内存是扩充什么,怎么增加电脑内存 三种方法让你电脑内存扩大
  19. 全球与中国小龙虾市场深度研究分析报告
  20. 【“BattenSnakexjp4.1”数据结构课程设计报告】

热门文章

  1. GPT解读(论文 + TensorFlow实现)
  2. 前端模板渲染插值语法加判断渲染v-if和v-else判断渲染
  3. ZYNQ - 以太网远程更新SD卡应用程序
  4. 放射科信息服务器瘫痪,【身边故事】清明假日,CT突发故障“罢工”“休假”!放射科紧急动员加班加点确保患者检查需求!...
  5. 女装店新开业,只做了一个小活动,疯狂引流并锁定顾客持续消费!
  6. 利用.htaccess来禁止某IP访问
  7. springboot跳转html_畅游Spring Boot系列 — 自定义配置
  8. Centos防火墙的一键开启与关闭
  9. 摩托罗拉手机前途系于Android手机
  10. 用平静的心去看文档读代码!