改进集合体验——更换集合组件
备注:本文针对tp5.0,由于tp不同版本的兼容性问题很多,以下这些内容仅供参考。
编程本来很痛苦,用框架目的则是想能更快更开心地开发。但了解一个框架是有成本的,也是有风险的。很多人选框架,只是看网上推荐,而不是做源码架构分析,更不看github中相关测试覆盖率以及代码质量标识。所以,一般情况下,这种选框架的方式多数是选tp、ci等,这种做法就是让自己入坑,就是找抽。一旦发生了,我们只能设法弥补。因为,推倒重来的成本太大了。本系列文章则是记录了作者,作为Laravel用户接手tp项目后的不断被虐待以及不断折腾的改进体验的过程。
没有比较就没有伤害。如果你是一个Laravel用户,你肯定因为tp的开发体验抓狂。其实,即使你是symfony用户,cake用户,yii用户,感觉也一样。因为,这些框架的开发体验都比tp好。cake在国内一直未成气候。而选ci的多数是初学者,觉得比tp简单。
当然,号称10年磨一剑的tp5很多地方现在好像都是在抄袭或模仿Laravel,有些是复制粘贴,但用的都是早期版本,针对现在,根本不够用。比如,collection就是这样的。有些是改写或模仿,但更让人抓狂。比如Model就是这样。这个类中,超过百行的函数相当多,If嵌套5到8层也是超级的多。
现在程序员都崇尚Clean Code,崇尚Don't Write Next Loop。 为什么呢?因为,人生短暂,开发速度最为重要。
tp的collection应当只有Laravel4或5具有的功能。所以,要想优化开发体验,那就要换掉它。为什么要换呢?因为迫不得已。项目不是你定的。你只是接手别人的项目。换框架,一切都要重写。可你不甘心被tp虐待,或许,领导还要你慢慢迁移到Laravel,你能怎么办?最好的办法就是局部替换,蚕食掉原来让你痛苦的一切。
怎么换呢?第一,你可以安装从第三方从Laravel剥离的Collection包tightenco/collect。当然,现在更好的是Laravel illuminate/collections包本身就能独立安装。所以,你也可以安装官方的包。两个包的不同之处,非官方的,还送了dd。dd有多好,谁用谁知道。
当然,安装完成以后,并不是直接能用了。tp与Laravel的Collection相关助手函数是一样的。
所以,你要测一下,看看collect函数最终创建的是哪个对象。如果仍是tp的,那么,有以下几个途径。
1,直接修改tp助手函数源码。注解掉与Laravel Collection同名的函数。
2,相对于更高级一些用户,你可以自己另写一套助手函数。
但现在问题是,数据库查询结果所用的Model中仍然是tp的Collection。tp在配置中就是用的Collection这个类,结果是,这两个类同名,除非改类型,否则,改配置没有用(很让人不爽)。不过,仍可以修改。方法是,你创建一个类BaseModel,继承tp的Model,然后,把tp的Model中的toCollection方法源码复制过来,改成调用Laravel的Collection。那么,接下来,实体的Model全部继承你刚刚实现的BaseModel就可以了。这样的话Laravel集合中的分组,排序,分页等你就都能用上了。代码如下:
...
use Tightenco\Collect\Support\Collection as ModelCollection;
...
/**
* Class BaseModel
*
* @package app\api\mpmodel
*/
class BaseModel extends Model{
...
/**
* 转换当前模型数据集为数据集对象
* @access public
* @param array|\Tightenco\Collect\Support\Collection $collection 数据集
* @return \Tightenco\Collect\Support\Collection
*/
public function toCollection($collection){
if ($this->resultSetType) {
if ('collection' == $this->resultSetType) {
$collection = new ModelCollection($collection);
} elseif (false !== strpos($this->resultSetType, '\\')) {
$class = $this->resultSetType;
$collection = new $class($collection);
}
}
return $collection;
}
...
复制代码
到此,集合Collection组件成功替换完成。剩下的,就是让模型继承你刚刚实现的模型。其次是用集合换掉现在可以换掉的所有的循环。你会觉得神轻气爽。确实是的,一切将会越来越好,并且,不久的将来,你将会用上全世界排名第一的Laravel框架。加油!