框架下载地址:版本5.0.24
http://www.thinkphp.cn/down/framework.html
TP5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 tp5 ├─application 应用目录 ├─extend 扩展类库目录(可定义) ├─public 网站对外访问目录 ├─runtime 运行时目录(可定义) ├─vendor 第三方类库目录(Composer) ├─thinkphp 框架核心目录 ├─build.php 自动生成定义文件(参考) ├─composer.json Composer定义文件 ├─LICENSE.txt 授权说明文件 ├─README.md README 文件 ├─think 命令行工具入口 如果在linux环境下面的话,需要给runtime目录755权限。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ├─thinkphp 框架系统目录 │ ├─lang 语言包目录 │ ├─library 框架核心类库目录 │ │ ├─think think 类库包目录 │ │ └─traits 系统 traits 目录 │ ├─tpl 系统模板目录 │ │ │ ├─.htaccess 用于 apache 的重写 │ ├─.travis.yml CI 定义文件 │ ├─base.php 框架基础文件 │ ├─composer.json composer 定义文件 │ ├─console.php 控制台入口文件 │ ├─convention.php 惯例配置文件 │ ├─helper.php 助手函数文件(可选) │ ├─LICENSE.txt 授权说明文件 │ ├─phpunit.xml 单元测试配置文件 │ ├─README.md README 文件 │ └─start.php 框架引导文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 ├─application 应用目录(可设置) │ ├─index 模块目录(可更改) │ │ ├─config.php 模块配置文件 │ │ ├─common.php 模块公共文件 │ │ ├─controller 控制器目录 │ │ ├─model 模型目录 │ │ └─view 视图目录 │ │ │ ├─command.php 命令行工具配置文件 │ ├─common.php 应用公共文件 │ ├─config.php 应用配置文件 │ ├─tags.php 应用行为扩展定义文件 │ ├─database.php 数据库配置文件 │ └─route.php 路由配置文件
引导文件
start.php文件就是系统默认的一个引导文件
在引导文件中,会依次执行下面操作:
加载系统常量定义;
加载环境变量定义文件;
注册自动加载机制;
注册错误和异常处理机制;
加载惯例配置文件;
执行应用;
start.php引导文件首先会调用base.php基础引导文件,某些特殊需求下面可能直接在入口文件中引入基础引导文件
控制器与模板跳转
控制器->模板
内置了一个基于XML的编译型模板引擎
控制器类继承think\Controller类之后,可以直接使用封装好的assign和fetch方法进行模板变量赋值和渲染输出
控制器
1 2 3 4 5 6 7 8 9 10 11 12 public function index() { $data = Db::name('data')--->find(); $this->assign('result', $data); $this->assign([ 'temp_id'=>$temp_id, 'templateinfo'=>$temptinfo, 'members'=>$mems ]); return $this->fetch(); return $this->fetch('add');// }
视图
1 2 3 {$result.id}--{$result.data}//1--thinkphp 模板标签的用法和Smarty类似,就是用于输出数据的字段,这里表示输出think_data表的id和data字段的值。
若fetch方法中没有指定任何模板,则按照系统默认的规则(视图目录/控制器/操作方法)输出了view/index/hello.html模板文件
模板->控制器
5.0的URL访问受路由决定,如果关闭路由或者没有匹配路由的情况下,则是基于
1 http://serverName/index.php(或者其它应用入口文件)/模块/控制器/操作/参数/值...
重定向:return $this->redirect(‘index/login/index’);(模块名/控制器/方法)
系统渲染模板 return view(‘index/login/index’);//不经过方法,直达视图
或者return t h i s − > f e t c h ( ) ,默认模板。 this->fetch(),默认模板。 t h i s − > f e t c h ( ) , 默 认 模 板 。 this->fetch(‘XXX’),指定跳到xxx模板,与view()相同
thinkphp视图中{:url()}或者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 //配合ajax的提示后的加载 $("#addForm").submit(function(){ // $('#save').attr('disabled',true); $.ajax({ url: "{:\\think\\Url::build('contract/addfirst')}", data: $(this).serialize(), dataType: "json", type: "post", success: function(data){ if (data.code==1) { if (data.code === 1) { parent.layer.msg(data.msg, {icon: 1, time: 1500}); window.location.href = "{:\\think\\Url::build(\'contract/contractfirst\')}"; } else { parent.layer.msg(data.msg, {icon: 2}); } } else { parent.layer.msg('服务器错误,请重试', {icon: 2}); } }, }); return false; });
模块和模块之间的关系
其他
数据库配置 文件application/database.php中添加数据库的连接信息
添加模块
1 php think build --module demo(模块名)
调试模式: 应用配置文件(application/config.php)
1 2 3 // 关闭调试模式 'app_debug' => false, 避免泄露你的服务器WEB目录信息等资料,一定记得正式部署的时候关闭调试模式。
命名空间
app命名空间通常表示文件的起始目录为application,而think命名空间则表示文件的目录为thinkphp/library/think
有几个关键的路径
1 2 3 4 5 tp5 项目根目录 ROOT_PATH tp5/application 应用目录 APP_PATH tp5/thinkphp 框架核心目录 THINK_PATH tp5/exend 应用扩展目录 EXTEND_PATH tp5/vendor Composer扩展目录 VENDOR_PATH
路由共有4种形式
基本get形式
http://域名/index.php?m=分组&c=控制器&a=操作方法
该方式是最底层的get形式、传统的参数传递方式,不时尚、不安全。
pathinfo路径形式[默认方式]
http://域名/index.php/分组/控制器/操作方法
http://域名/index.php/Home/Index/advert
rewrite重写形式(伪静态技术)省略index.php入口文件
http://域名/分组模块/控制器/操作方法(用过了)
http://域名/Home/Index/index
兼容形式
http://域名/index.php?s=/分组/控制器/操作方法
http:/域名/index.php?s=/Home/Index/advert
参考链接:
https://www.w3cschool.cn/thinkphp/xi581rtn.html
https://blog.csdn.net/voke_/article/details/78766663
https://blog.csdn.net/weixin_39768635/article/details/78195443
数据库配置文件:
1 2 yunyi\application\extra\database_news.php(数据库配置文件) yunyi\application\database.php(这个才是)
sql调用:
原生的:
TP的模型可以支持原生SQL操作,提供了query和execute两个方法
query用于查询,返回的是数据集,和select或者findall一样,所以可以直接在模板里面使用volist标签输出query的查询结果,注意query是查功能、插入
execute用于写操作,返回的是状态或者影响的记录数,注意execute是增删改功能
只是需要new一个空的模型继承Model中的方法
查
1 2 3 4 5 6 $Model = new Model();//或者 $Model = D(); 或者 $Model = M(); $sql = "select * from `order`"; $voList = $Model->query($sql); Db::query("select * from think_user where status=1"); 如果你当前采用了分布式数据库,并且设置了读写分离的话,query方法始终是在读服务器执行,因此query方法对应的都是读操作,而不管你的SQL语句是什么。
增删改
1 2 3 4 $voList = $Model->execute('update think_user set status=1 where id=1'); Db::execute("update think_user set name='thinkphp' where status=1"); 如果你当前采用了分布式数据库,并且设置了读写分离的话,execute方法始终是在写服务器执行,因此execute方法对应的都是写操作,而不管你的SQL语句是什么。
封装的:
增(add)
1 2 3 4 5 6 7 8 9 $model = M('WxuserCollection'); $data = array('user_id' = >$user_id, 'store_id' = >$store_id, 'good_id' = >$good_id, 'addtime' = >$addtime); $model - >data($data) - >add(); $User = M("User"); // 实例化User对象 $User->where('id=5')->setInc('score',3); // 用户的积分加3 $User->where('id=5')->setInc('score'); // 用户的积分加1 $User->where('id=5')->setDec('score',5); // 用户的积分减5 $User->where('id=5')->setDec('score'); // 用户的积分减1
改(edit)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $model = M('WxuserCollection'); $data = array('user_id' = >$user_id, 'store_id' = >$store_id, 'good_id' = >$good_id, 'addtime' = >$addtime); $model - >data($data) - >where('id=3') - >save(); $goods=D("emptest"); $goods->name="Cool"; $goods->garde="2"; $goods->email="Cool@qq.com"; $goods->salary="7777"; $goods->where('id=2')->save(); $goods=M("emptest"); $arr=array('id'=>'7','name'=>'xu2xuning','salary'=>5555); $res=$goods->save($arr);
查(find与select,field,order,join,getField)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 $model = M('WxuserCollection'); $res1 = $model - >find(1); $res2 = $model - >find(2); $res3 = $model - >where('good_id=1105 AND store_id = 1 AND user_id = 20') - >find(); find(1)获取id为1的数据,find(2)获取id为2的数据。最后一个是获取条件为where的中的第一条数据 $model = M('WxuserCollection'); $res = $model - >where('good_id=1105 AND store_id = 1 AND user_id = 20') - >field('id,good_id as good') - >select(); 获取所有数据。这里的好处就是,不用考虑sql语句的顺序了,随心所欲调用函数就可以了 $res = $model - >field('id,good_id as good') - >select(); $res = $model - >field(array('id', 'good_id' = >'good')) - >select(); $res = $model - >field('id', true) - >select(); 字符串,数组两种方式,第三个是表示获取处理id之外的所有字段 $res = $model - >order('id desc') - >select(); $res = $model - >order(array('id' = >'desc')) - >select(); 字符串,数组两种方式,默认asc。 $Model->join(' work ON artist.id = work.artist_id')->join('card ON artist.card_id = card.id')->select(); $Model->join('RIGHT JOIN work ON artist.id = work.artist_id')->select(); $Model->join(array(' work ON artist.id = work.artist_id','card ON artist.card_id = card.id'))->select(); 默认采用LEFT JOIN 方式,如果需要用其他的JOIN方式,可以改成第二种, 如果join方法的参数用数组的话,只能使用一次join方法,并且不能和字符串方式混合使用。
getfield
1 2 3 4 5 6 7 8 9 10 11 // 获取ID为3的用户的昵称 ,即使有满足条件的多个字段,也只会返回一个结果 $nickname = $User->where('id=3')->getField('nickname'); 返回的nickname则是一个数组,包含了所有满足条件的昵称列表。 $nickname = $User->where('status=1')->getField('nickname',true); 限制返回结果数量 $nickname = $User->where('status=1')->getField('nickname',8); 2字段名称的话,默认返回一个关联数组,以第一个字段的值为索引(所以第一个字段要尽量选择不会重复的) $nickname = $User->where('status=1')->getField('id,nickname'); 2个以上的字段名,则返回一个二维关联数组(类似select方法的返回值,区别在于索引是二维数组的键名是第一个字段的值) $result = $User->where('status=1')->getField('id,account,nickname');
删(delete)
1 2 3 4 5 $model = M('WxuserCollection'); $res = $model - >where('id=1') - >delete(); // 成功返回1 失败返回0 $model->delete(9);//删除指定主键的数据行 $model->delete(”1,2,3“);//也可以删除多个主键的值得行,一定要带引号 $model->where("id>=13 and id<=18")->delete();//条件性的删除操作
实践
1 2 3 4 $where = array('a.store_id' => $this->store_id, 'a.user_id' => $this->user_id); $collects = $this->collectModel->table("sh_wxuser_collection a")->field(array('b.name','b.price','b.oprice','b.logoimg','a.goods_id'))->limit($start, $offset)->order('a.addtime DESC')->where($where)->join(' sh_goods b ON a.goods_id = b.id')->select();// 获取当前页的记录 echo M()->getLastSql(); // 调试sql语句用 $count = $this->collectModel->table("sh_wxuser_collection a")->where($where)->count(); // 获取总的记录数
参考链接: https://www.cnblogs.com/jiqing9006/p/4975293.html
OOP与AOP
Aspect Oriented Programming(AOP) 面向切面编程
例如:对 “权限检查”这一动作 片断进行封装
Object Oriented Programming (OOP)面向对象编程
例如:将“雇员”相关的属性和行为封装入 “Employee”类中