「七天自制PHP框架」第四天:模型关联

往期回顾:「七天自制PHP框架」第三天:PHP实现的设计模式,点击此处php

原文地址:http://www.cnblogs.com/sweng/p/6624845.html,欢迎关注:编程老头html

前阵子在网上关心一个话题:对于一个PHP程序员,或者Java程序员,或者C#程序员,怎么区分3年,5年,10年工做经验?工做经验是否和薪资成正比?前端

我的认为:不管擅长哪种语言,都不要把本身绑在一种语言上,更不要作一个代码的搬运工。平时每写完一个项目,都留出充足的时间去思考“还有什么地方能够改进”,相信即便1年的工做经验,也会有3年工做经验的收获。程序员

最近我在思考一个问题:平时作PHP项目经常要和“新闻发布”,“博客评论”打交道,而每一次写功能都会重写“类似”的代码,若是可以把这一块代码作好重用,之后只需修改几个参数就能用在另外一个项目,就能够很短期完成一个功能。sql

固然使用PHP框架,会让你工做效率获得成倍的提高,可是,你的学习成本也就跟着上去了。数据库

最初使用Laravel框架的时候,以为Eloquent的语法实现得很美,好比:编程

$comments = App\Post::find(1)->comments;

foreach ($comments as $comment) {
    //
}

这里继续咱们上一节讲的,怎么作模型关联。json

模型,简单点说,就是把数据库中这么多表抽象成若干个对象,使得开发的过程当中,不用再关心数据表的结构,而是专心类和对象的设计。设计模式

就拿在微信朋友圈发消息来讲,这里涉及到了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格式输出,结构一目了然,给前端调用也很便利。

相关文章
相关标签/搜索