Yii项目开发总结
学习Yii很久了,一直做的是小案例,自以为学的还不错。直到最近用Yii开发了一个非常简单的CMS,一路下来,磕磕绊绊,才知自己不足。加上最近正学习着偏架构方面的知识。特此总结一下。小白经验,大神轻拍,欢迎讨论。
本篇文章主要是将一些 MVC 代码组织的技巧,不会涉及详细编码。声明使用的模版是Yii高级模板。
痛苦的开发。
所有的php框架几乎都遵循MVC模式设计,网络各种教程、官方手册,也是一股脑的说着按着MVC组织代码。
先说说开发中我的悲惨历史。
大家都知道,在Yii中,一张表对应一个AR,再对应一个控制器。
在开发开始的时候确实是不错的。比如留言功能里面。我在common\models下生成了对应的AR类。然后在frontend和backend的控制器里导入了这个AR类,修改相应视图。然后根据需要对查询做了简单封装,即是在生成的AR类中写了一些方法,然后控制器调用。功能实现,代码逻辑也清晰。自觉棒棒哒。
然后就到痛苦的时候了。在设计文章和栏目的时候,我分了三张表:文章表,栏目表,文章内容表。在common\models生成三个AR类,后台、前台分别调用。由于创建文章时三张表都需要同时用到,以及插入、修改、删除的时候,需要用事务保证一致性。于是我只能就在文章的控制器里添加了一个又一个涉及数据库操作的方法。然后在前台显示的时候,又在对应的模型类里添加了一些方法,前台控制器又是一般修改。首页显示的控制器,映入了八个AR类。然后到最后,看着控制器里一个个AR查询的方法,AR类中又是一堆不同的查询方法,我彻底懵逼了。
好不容易实现完功能,自己都不敢看自己的代码了。
MVC中M的思考
开发完之后,痛定思痛。在大量阅读博客、书籍之下。获得以下经验,与君共享。
关于MVC中,首先声明的一点是设计要“胖Model痩Controller”,即Controller应该只有薄薄的一层。主要业务逻辑都在Model中。
视图层和控制层不用多谈,大家都知道。主要该谈谈的是模型层。
模型中前后台的组织
对于前后都要用到的模型,大家都会生成AR类到common\models,然后在frontend和backend的控制器里导入了这些AR类。但是,这不是一个好的习惯。前后台有着不同的应用逻辑。引用同一个AR类必然职责不清。正确的做法是在前后台的models文件夹里,新建不同的类,然后继承common\models中的AR类,做到模型分离。
举个例子。在common\models中有个Post.phpAR类,你应该在backend\models中新建一个Post.php然后继承common\models中的Post.php类。前台也是如此,做到引用分离。
业务逻辑层(service)
开发中必定涉及到多表关联。如果全部在控制器中引入模型类,写查询语句,代码组织就会非常糟糕,不利于维护管理,更正确的做法是。建立一个业务逻辑层(service)。
也就是做backend和frontend文件夹下建立一个services文件夹,保存我们的业务逻辑。比如我前面有三张表:文章表,栏目表,文章内容表,分别对应三个模型。当我需要保存一片文章时,同时涉及到三张表的操作。我就可以建立一个PostService.php,里面引入这三个AR类,然后建立一个SavePost()方法,在方法里同时对三张表做操作。这样,控制器里只需引入这个服务类,调用相应方法就行了。
读写分离。
实际的应用都是读多写少,因此,我们可以做到代码层面的读写分离。(详细的可以了解了解CQRS架构),方便分别优化。而且Yii中的AR虽然很方便,但是效率不高,太复杂的查询也是不好实现的。
这里Yii提供了一个简单高效的SQL查询。那就是DAO。
就是使用方式是这个的东西。
$post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status')
->bindValue(':id', $_GET['id'])
->bindValue(':status', 1)
->queryOne();
我们可以在services文件夹里建立只提供查询的文件,比如PostQuery.php文件提供对文章的查询
总结
第一次开发一个完整的东西,学习到了很多。最近打算对这个CMS进行重构。道路阻且长,加油!


写的不错!我也是刚刚学习,交流下经验。对于model层,我一般都是放在common中,但是为了防止混淆,我会建立表单模型,譬如:Post.php,我会让它对应一个PostForm.php(继承自Model),让它处理业务逻辑,Post.php仅仅处理简单的数据操作或者完全就是一个数据模型。如果,按照楼主的方法,虽然前后端代码分离的更加清晰,但是我想这样做代码是不是会有很多重复了。。毕竟,模型层的操作会有很多一样的。
共 1 条回复
bubifengyun 评论于 2016-12-02 13:26举报相当不错。我的也是都放在
common/models只有特殊的才放在 各自frontend或backend文件夹下。都没有考虑过继承。

huangboyii 评论于 2016-12-12 14:17举报AR模型虽然效率低一些,但是有更多的高级功能。比如事件,行为,事务等等。拿写操作来说,AR模型中提供beforeSave, afterSave这这两个方法,这两个方法会触发相应的事件,你可以在这些事件上绑定一些事件处理器完成对写流程的控制或者完成额外的一些操作,这是Yii2操作数据库最为高级的方式,也是最精华的优点之一。个人以为,牺牲点运行性能,增加开发和理解上的便利性是划算的。
共 2 条回复
不好意思,是我没有表述清楚。我说的是代码层面的读写分离。并不是全用 SQL 语句。
数据库操作就涉及增、删、改、查,其中增、删、改都是会对数据库的内容的状态造成改变,而查操作是不会对数据产生修改的。
针对这个特性,我们可以在代码层面做出读(即查)写(即增、删、改)分离。便于针对不同的优化。
我提出的是,写操作使用 AR 模型,读操作则直接用 SQL 语句。
原因有这么几点:
- 一般的应用中80%是读,20%是写,或者更高。AR 效率低,用来做读性能消耗太大。
- 使用 AR 做读的话,全部采用面向对象的方式,一些复杂的查询不宜实现。
- 其次使用 AR 做读,你并不了解最终生成的 SQL 是什么样的。检测到一些SQL语句执行过慢时,AR 中不好优化。
其实究根结底,最终还是为了性能和维护。
huangboyii 评论于 2016-12-20 09:26回复我认为你的观点——使用AR模型做写操作,而用SQL做读操作非常有道理。Yii的读操作也是分为几个层次,原生态上SQL,DAO和AR模型。DAO的方式读,也提供了Query和BuildQuery帮你生成复杂的SQL语句,但是执行的方式几乎还是和PDO一样,所以效率高的同时,方便性也得到保障。
Yii项目开发总结的更多相关文章
- yii项目开发配置
Clone项目 git clone https://gitee.com/s***/dianshang.git 安装yii php ini 选择 [0] Development 安装扩展 copy co ...
- yii项目开发项目常用技巧和方法汇总
1.使用CActiveForm类组件如何输出不带html属性的结果 eg:<?php echo $form->textField($model,'email',array('size'=& ...
- YII框架开发一个项目的通用目录结构
YII框架开发一个项目的通用目录结构: 3 testdrive/ 4 index.php Web 应用入口脚本文件 5 assets/ 包含公开的资源文件 6 css/ 包含 CSS 文件 7 ima ...
- MVC模式学习--雇员管理系统项目开发
1, 项目开发,使用原型开发, ① 开发流程: 需求分析->设计阶段->编码阶段->测试阶段->发布阶段/维护阶段 需求阶段:PM/项目经理 对客户 设计阶段:技术人员(架构师 ...
- Android快乐贪吃蛇游戏实战项目开发教程-01项目概述与目录
一.项目简介 贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏. 我已经将做好的案例上传到了应用宝,无病毒.无广告,大家可以放心下载下来把玩一下.应用宝 ...
- HTML+CSS项目开发总结
好几天没更新博客了,刚实战完一个HTML+CSS的简单项目.经过几天的摸索,发现收益良多.之前只是单纯得写demo,看知识点,没有亲自实战项目.但实战过后才会了解,如何才能更好地提升自己的技术.针对这 ...
- 简历生成平台项目开发-STEP2问卷调查结果统计分析
根据之前设计的调查问卷,截止目前为止,一共收到64份问卷结果.一共16题,分别从基本信息.是否对简历制作有需要.对产品期望的特点和建议采纳四个方面设计问题.下面逐题分析问卷结果: 1.您的性别 可以看 ...
- 如何使用Worktile进行敏捷项目开发管理
Worktile在任务管理上采用了看板视图,非常适合进行敏捷项目开发管理.事实上,在开发Worktile的过程中,我们也是自产自销,使用Worktile管理Worktile本身的开发过程,在本文中跟大 ...
- Java进击C#——项目开发环境
本章简言 上一章我们了解一下开发环境,知道了什么去新建一个项目工程.却并没有去项目工程进行介绍.可是之后我们会常常跟项目工程打交道.所以这章笔者就对项程工程的常用的一些功能进行讲解.当然说全面那是不可 ...
随机推荐
- 架构-架构风格:RESTful
ylbtech-架构-架构风格:RESTful 一种软件架构风格.设计风格,而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层 ...
- 浅谈PHP面向对象编程(三、构造方法和析构方法)
3.0 构造方法和析构方法 从我之前的博客可以发现,实例化一个类的对象后,如果要为这个对象的属性赋值,需要直接访问该对象的属性.如果想要在实例化对象的同时就为这个对象的属性进行赋值,则可以通过构造方法 ...
- Java 内存机制、内存泄露
http://wenku.baidu.com/view/61f31da6284ac850ad02423e.html 自己注:hashset和hashmap不同 JDK1.6 API 中 HashSet ...
- input标签存在的兼容问题?
当input标签在type为text时,在Firefox和Safari中的默认高度为22像素(包括上下边框)宽度为146像素(包括左右边框),而在IE中的默认高度为24像素,而宽度却和Firefox和 ...
- DOM笔录
文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口.它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式.我们最为关心的是,DOM把 ...
- tornado 自定义session (一)
tornado 中没有session功能,需要我们自己实现. 目录: settings: settings = { 'template_path': 'templates', 'static': 's ...
- 解读linux中用户密码规则及忘记root口令的破解(思路)
linux当中,用户名和密码表对应关系放在/etc/passwd中,如: root:x:0:0:root:/root:/bin/bash 格式代表意义分别为 用户名:密码:用户id:组id:用户描述 ...
- 利用redis限制单个时间内某个mac地址的访问次数
一.思路 用户mac地址唯一,可以作为redis中的key,每次请求进来,利用ttl命令,判断redis中key的剩余时间,如果大于零,则利用incr进行+1操作,然后再与总的限制次数作对比. 二.代 ...
- Linux 统计当前目录下文件数
Linux 统计文件数 linux统计当前目录下文件数 ls -l |grep "^-"|wc -l linux统计当前目录下文件(包括子文件夹下的)数 ls -lR|grep & ...
- java 蓝桥杯算法提高 _1区间k大数查询
import java.util.Scanner; public class _1区间K大数查询 { public static void main(String[] args) { Scanner ...