TP5 小知识(5.1.x)

版权声明:看,这是一只有梦想的程序猿 - by Pendant。 https://blog.csdn.net/benpaodelulu_guajian/article/details/78488938

tp5 路由相关:

Route::domain('api.com', 'api');
# 路由1
Route::get('v1/users/recordDetail','@api/v1.users/recordDetail');
# 路由2
Route::get('v1/users/recordDetail','v1.users/recordDetail');

域名已经绑定模块的前提下:

路由1中 又绑定了模块,这个时候 如果在config里面 采用模块配置 (新建api文件夹,里面写配置文件)这种情况下 配置参数无法获取。只能是在config文件夹下 直接新建api.conf 在其中写配置参数 才能用config()正常获取 。

路由2中 没有再次绑定模块,这个时候 如果在config里面 采用模块配置 (新建api文件夹,里面写配置文件)或者是在config文件夹下 直接新建api.conf 在其中写配置参数 config()都可正常获取 。

2019年1月14日

tp5 事务相关:

tp5.1.29 开启事务后,在try catch中 不能使用助手函数 db()->xxxx,助手函数db() 不支持事务回滚。5.2版本(已更名6.0)已经取消助手函数了,更符合规范。

按照官方文档上 try catch中应该使用 Db::name()  或者 Db::table()

如果事务中涉及同一张表插入多条不同数据  推荐使用 saveAll ,  saveAll中为非空二维数组,如果有主键,还需要插入,saveAll第二个参数 为false  详情参见 官方文档

2018年12月10日

 

tp5 路由相关:

 get 方式注册路由,严格区分路由方法的大小写

Route::get('v1/users/recordDetail','@api/v1.users/recordDetail');

Route::get('v1/users/recorddetail','@api/v1.users/recordDetail');

上面是两个不同的路由。

2018年12月7日

 

tp5 路由相关:

Route::get('v1/users/record/[:type]/[:p]','@api/v1.users/record')->pattern(['p' => '\d+','type' => '\d+']);

规则如上所示:定义的第一个参数是type   第二个是p
 

v1/users/record/1/2 

input('param.type')   // 1
input('param.p')      // 2
Route::get('v1/users/record/[:p]/[:type]','@api/v1.users/record')->pattern(['p' => '\d+','type' => '\d+']);

规则如上所示:定义的第一个参数是p   第二个是type

v1/users/record/1/2 

input('param.type')   // 2
input('param.p')      // 1

  综上所述:严格按照路由规则中参数的顺序匹配参数

 

同时,如果不是可选参数,那么在方法中的默认参数就是路由参数:

Route::get('v1/users/record/:type/:p','@api/v1.users/record')->pattern(['p' => '\d+','type' => '\d+']);

路由规则如上所示,获取参数可以: 

注意:这种形式的 只能以pathinfo的形式传参,query形式的(?type=1&id=2)是无效的

public function record($type, $p)
{
    echo $p, $type;
}
或者 不给函数设置参数,在函数内直接 input('param.type'),   input('param.p') 也可获取
这种用pathinfo  或者query形式 传参都可正常接收

2018年12月5日

 

tp5 模板里获取当前pathinfo格式的url参数
http://test.local/user/index/id/3
 

{$Request.param.id}    即可正常获取 3

2018年11月2日

 

多级控制器的资源路由注册:

// 完整域名绑定到admin模块
Route::domain('route.local', 'api');
// api接口路由
Route::resource('v1/test','api/v1.test',['domain'=>'route.local']);
Route::resource('v1/UserType','api/v1.UserType',['domain'=>'route.local']);

以上面的为例,当访问 route.local/v1/test   会路由到  api模块下的 controller/v1/test.php 中的 index方法。

资源路由比下面的全动态路由更加规范,基于 restful api 风格。

2018年10月8日

 

根据url里的版本号访问不同的接口的配置(api.dmain.com/v1/user):

前提条件:绑定好了模块,隐藏了入口文件index.php

然后看路由,如果url是 api.domain.com/v1/user

参考tp5文档里面的多级控制器,如果采用多及控制器,还想动态配置访问的控制器 需要开启控制器的自动识别(只能写在全局配置,路由相关的功能只能在应用配置中设置即 application/config.php

 

'controller_auto_search' => true,

然后就是注册路由 ,注意,ThinkPHP5.0的路由规则定义是从根目录开始,而不是基于模块名的。

Route::rule('<v>-<c>-<a>','v.c/a','',['domain'=>'route.local']);

这样访问 api.domain.com/v1/user  最终目录解析为  /api/controller/v1/user/index  即api模块下的controller控制器下的v1文件夹下的user控制器的index方法。我这里配置的只是一个例子,具体的还要加上域名检测等参数。

路由规则:

 

2018-5-19

 

 

关于tp5路由的一些想法,如果采用多入口文件,那么域名可以不变,只需访问不同的入口文件即可实现前后台分离,比如public 里面新建一个admin.php 绑定到admin模块,那么 www.xxx.com 访问的是前台,www.xxx.com/admin.php 访问的是后台,这种是最直接的前后台区分。

另一种应该是开启路由,使用路由,对于不同的域名进行前后台的区分,tp5有Route::domain() 可以根据子域名绑定模块,这样就可以在公共文件中把 admin.xxx.com绑定到 admin模块,www.xxx.com绑定到前台模块,api.xxx.com绑定到api模块(点击跳转

2018-5-17

 

 

模型传送门

2018-5-6

 

tp5 模型查询自动分页

官方手册上写的是在controller里 db(XX)->paginate(10);

在model里采用分页可以这样写

当前model查询出数据对象$userList 然后分页可以用$userList调用render()这个方法,如果你的$userList 是数组 就会报错:Call to a member function render() on array 。控制器中接收到返回值如下处理:

模板上只需要{$page}即可显示分页。

可在官方手册上搜索:分页

仔细查看文档即可。

2018-4-11

 

tp5 表单提交的数组获取值的时候报错 ariable type error:array 那么需要加一个修饰符

官方手册:

2018-4-7

 

官方手册上查询数据都是在控制器直接db('xx')->select();如果在controller里调用model里查询数据的方法,那么返回给控制器的一般是数据对象,如何把tp5在model里查询出的数据对象转化为数组呢,手册上说:5.0.4+ 支持模型中单独设置查询数据集的返回对象的名称:

这样打印的结果$menulist 即为数组类型。

18-3-31

 

1.tp5获取前端传过来的值

用tp3的时候,表单传的值直接用$_POST获取,今天用到tp5的时候,看到了助手函数里面的input(),支持默认值和过滤。

input($key = '', $default = null, $filter = '') //变量名,默认值,过滤方法

例如

input('post.comments', '挂件', 'htmlspecialchars');

 

2.tp5的model里查询结果返回的是对象,那怎么获取data里面的数据呢?

比如$res是返回的对象, 它的data里面有我们查询的id和username,

如果是用的find()直接 $res['id']  $res['username'] 即可获得。

如果是select() 那么是二维数组,$res[0]['id'],$res[0]['username'] 即可获得二维数组中的键为0的数组的相关值

有兴趣知道原因可看:

http://blog.csdn.net/qq_15096707/article/details/62227624

 

3.tp5 点击更换验证码js

onclick="javascript:this.src=this.src+'?time='+Math.random()" 

直接写在验证码的img标签里面,不用写函数了。

tp5验证码常用配置:写在全局config.php里面即可。

 

    'captcha' =>    [
    		//验证码字符集合
    		'codeSet' =>		'ASDFGHJKLPUYTREWQXCVBNM123456789asdfghjkmnbvcxqwertyp',
    		// 验证码位数
    		'length'      =>  4,
    		//验证后重置
    		'reset' 	=>	true,
    		//图片宽度
    		'imageW'	=>	150,
    		//图片高度
    		'imageH'	=>	30,
    		//使用背景图片  
    		"useImgBg"  =>false,
    		//验证码字体大小(px)
    		"fontSize"  =>	17,
    		//是否画混淆曲线
    		"useCurve"  =>  true,
    		//是否添加杂点  
    		"useNoise"  =>	false,
    		//验证码过期时间(s)
    		"expire"  =>	600,
    ],

 

 

 

 

 

4.tp5 数据库操作新增或保存save()

 

 

模型的新增和更新方法都是save方法,系统有一套默认的规则来识别当前的数据需要更新还是新增。

  • 实例化模型后调用save方法表示新增;
  • 查询数据后调用save方法表示更新;
  • save方法传入更新条件后表示更新;

 

如果你的数据操作比较复杂,可以显式的指定当前调用save方法是新增操作还是更新操作。

显式更新数据:

// 实例化模型
$user = new User;
// 显式指定更新数据操作
$user->isUpdate(true)
    ->save(['id' => 1, 'name' => 'thinkphp']); //最好不要用这个,直接update(条件)来更新

显式新增数据:

$user = User::get(1);
$user->name = 'thinkphp';
// 显式指定当前操作为新增操作
$user->isUpdate(false)->save();

手册上有声明:注意不要在一个模型实例里面做多次更新,会导致部分重复数据不再更新,正确的方式应该是先查询后更新或者使用模型类的update方法更新。 

那么更新的时候 直接 $user->update('条件')即可,可不用save()来更新。

新增的时候 用save() 最好指定 isUpdate(false)。

 

 

 

5.{:url()}里面用变量是不需要引号的,也就是说 直接 {:url($val['url'])} 即可正确解析

18-4-1

 

 

6.tp5 ajax请求返回渲染后的模板

 

 

这个问题出现的原因是因为我想局部刷新左侧菜单,但是我通过返回的数组用Js追加元素的方式刷新以后会出现布局的偏移,虽然是一点点,但是很难受,最后想到了之前tp3.2.3可以直接返回模板,所以就想在tp5也这么处理,这样局部刷新就很简单,不用遍历数据,清空,追加等等操作。

正常的请求不都是 echo json_encode($arr)嘛,今天想着把渲染后的模板返回给ajax请求,试了半天也没试出来,

去TP官方论坛,特意找到了版主问了这个问题,版主几分钟后上线回答问题,没有回答我,估计是我问的太简单了。

最后在tp群里找到了解决的方法。

多次尝试代码如下:

 

	$this->assign('res_t',$res_t);  //模板赋值
	$html=$this->fetch('common/left'); //渲染模板,但是不直接return
	return  $html; //输出返回值  在这里输出的就是left.html的页面内容,输出的是字符串类型的

 

上面这个是自己结合群里提到的试验出来的,但是实际上还是要看手册,大腿告诉我,我这么写不规范,规范的写法应该是返回数组,通过js追加元素实现局部刷新,但是写法还是可以标准一些:

 

 

 

$this->assign('res_t',$res_t);
Config::set('default_ajax_return','html'); //配置ajax默认的返回格式
return $this->fetch('common/left'); //这样就不会输出模版,完成渲染并当作返回值,如果没有上面的配置,return $this->fetch()会报错

 

至于ajax接收到返回值,只需要用jquery转换成对象就可以了:

 

console.log($(data).html())   //这个输出的就是html内容。$(data) 就把返回值data由字符串格式转换成了对象


对于这个问题像个半天,总结了一下还是自己看手册没看全,如果知道更改了默认格式就可以 return $this->fetch();那么就不会折腾一下午了。当然,最后也发现遍历数组追加元素偏移的原因是一个class 属性少了一个字母...少了一个字母...一个字母....

 

 

 

当然了,这也是经验,毕竟自己踩过的坑,印象才最深刻偷笑偷笑,还是要感谢新加的群里的大神们的热心帮助,让我找到了解决问题的门路,独学而无友,则孤陋而寡闻。

当工作环境已经没人能给你思路,自己也看不见能让技术提高的机会的时候,趁着年轻,多走走。

 

 

7.tp5 url带参数,url传参数get不到

 

格式

 

 {:url('admin/index/index',['id'=>1,'name'=>'admin'])}


控制器里获得参数不能用$_GET

 

 

$request = Request::instance();
$res=$request->param();
halt($res);//包含id和name

 

8.tp5关联模型,关联模型后查询结果对象取值,关联模型在model里进行查询

 

 

后记:关联模型好像不能关联删除和更新(可能是我操作的不对,也可能是本身就不可以了),关联模型查询出来的数据对象取值又比较麻烦,鉴于不能关联删除,已经没有优势,还是用链式操作进行关联查询吧 (2017-11-29)

今天看了一下关联模型,在手册上的例子都是在控制器中直接查询数据,如果在model里查询数据该怎么关联查询呢?

首先,需要设置关联模型:

 

 	//关联模型
 	 public function connectmenushow(){  //一对一关联 还有一对多和从属关联,这里不列举了,去手册上看
        return $this->hasOne('AdminMenuShow', 'uid', 'id')->field('uid,menu_id');  
    } 

hasOne('a','b','c')//关联的模型a,外键b,当前模型的主键c

 

上面设置的关联模型为 adminmenushow这张表,外键是uid  当前表的主键是id 关联查询字段是uid 和menu_id(设置关联手册上有例子)

 

如果关联模型不懂的话 可以看这篇文章:http://blog.csdn.net/github_37512301/article/details/75675054

我想说的是查询数据和取出值:

手册上的例子是在控制器里用db 连接数据库查询,在model里这样查询:

 

	public function show_admin(){
		$res=self::with('connectmenushow')->select();//connectmenushow 是上面设置关联的函数名
		foreach ($res as $k => $v) {
			//关联模型数据对象
			$obj = $v->relation;
			$arr[$k]['menu_id'] = $obj["connectmenushow"]['menu_id'];   //这是关联模型的数据
			$arr[$k]['username'] = $v['username'];//主表数据
			$arr[$k]['password'] = $v['password'];//主表数据
		
		}
		halt($arr);
		
	}


主要用到了 with() ,打印结果是对象,但是对象里面有个relation属性,如图:

 

这里面包含上面关联模型设置的表里面的字段数据,获取这些数据要先从$v这个对象中选中这个属性,然后选中数组,然后先择相应的下标,这样即可获得关联查询的所有内容。

 

 

 

有帮助的话,点个赞,谢谢

展开阅读全文

没有更多推荐了,返回首页