往期回顾:「七天自制PHP框架」第三天:PHP实现的设计模式,点击此处
原文地址:http://www.cnblogs.com/sweng/p/6624845.html,欢迎关注:编程老头
前阵子在网上关心一个话题:对于一个PHP程序员,或者Java程序员,或者C#程序员,怎么区分3年,5年,10年工作经验?工作经验是否和薪资成正比?
个人认为:无论擅长哪一种语言,都不要把自己绑在一种语言上,更不要做一个代码的搬运工。平时每写完一个项目,都留出充足的时间去思考“还有什么地方可以改进”,相信即使1年的工作经验,也会有3年工作经验的收获。
最近我在思考一个问题:平时做PHP项目常常要和“新闻发布”,“博客评论”打交道,而每一次写功能都会重写“相似”的代码,如果能够把这一块代码做好重用,以后只需修改几个参数就能用在另一个项目,就可以很短时间完成一个功能。
当然使用PHP框架,会让你工作效率得到成倍的提升,但是,你的学习成本也就跟着上去了。
最初使用Laravel框架的时候,觉得Eloquent的语法实现得很美,比如:
$comments = AppPost::find(1)->comments; foreach ($comments as $comment) { // }
这里继续我们上一节讲的,怎么做模型关联。
模型,简单点说,就是把数据库中这么多表抽象成若干个对象,使得开发的过程中,不用再关心数据表的结构,而是专心类和对象的设计。
就拿在微信朋友圈发消息来说,这里涉及到了3个对象:消息(纯文字,图片,或者图文),点赞,评论。
根据这个图,我们设计三个类:
class MessageModel extends Model{ public static $data; public static $name; public $messageid; public function __construct(){ parent::__construct(); $this::$name='message_list'; $this::$table='message'; } } class LikeModel extends Model{ public static $data; public static $name; public $likeid; public function __construct(){ parent::__construct(); $this::$name='like_list'; $this::$table='messagelike'; } } class CommentModel extends Model{ public $commentid; public function __construct(){ parent::__construct(); $this::$name='comment_list'; $this::$table='reply'; } }
这是典型的“一对多”的模型,也就是一个Message对象对应了多个Like对象和Comment对象,而一个Like对象或者Comment只对应了一个Message对象。
有人说,为什么不用SQL中的where或者join来查询?
因为我实在厌倦了拼接SQL,实在太无趣了。
关键是查询完得到的多维数组,还需要写一段代码来组装成对象数组,让我不得不思考怎么避免这低效劳动。
我的方案是每一个Model都实现这样的接口,让你尽量少写select
public static function get($id){ return self::where('id',$id); } public static function where($condition,$value){ $sql=sprintf("select * from %s where %s='%s'",self::$table,$condition,$value); return self::$db->Query($sql); } public static function first($num){ $sql=sprintf("select * from %s limit %s",self::$table,$num); return self::$db->Query($sql); } public static function all(){ $sql=sprintf("select * from %s",self::$table); return self::$db->Query($sql); }
那如果要实现一对多,怎么办?Laravel使用了trait特性,让Model来use这个特性。
这里我们简单的做一个函数:
public function HasMany(Model $model,$foreignkey){ for($i=0;$i<count($this::$data);++$i){ $this::$data[$i][$model::$name]=[]; for($j=0;$j<count($model::$data);++$j){ if($this::$data[$i][$foreignkey]==$model::$data[$j][$foreignkey]){ array_push($this::$data[$i][$model::$name],$model::$data[$j]); } } } }
对于三张数据表:Message,Like,Comment来说,Message的主键是msgid,而msgid同时也是Like和Comment这两张表格的外键,靠着外键,三张表形成了一对多的关系。
所以凭借这样的一个关联数组的操作,我们把Like和Comment数组作为一个关联数组的Value塞入Message数组中的一个元素。
最后我们测试一下效果:
$messageModel=new MessageModel(); $messageModel::$data=$messageModel::all(); $likeModel=new LikeModel(); $likeModel::$data=$likeModel::all(); $commentModel=new CommentModel(); $commentModel::$data=$commentModel::all(10); $messageModel->HasMany($likeModel,'msgid'); $messageModel->HasMany($commentModel,'msgid'); echo json_encode($messageModel::$data);
我们最后使用JSON格式输出,结构一目了然,给前端调用也很便利。