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


    往期回顾:「七天自制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格式输出,结构一目了然,给前端调用也很便利。

    本文为博主原创文章,转载请在明显位置注明出处: http://www.cnblogs.com/sweng

    本作品采用知识共享署名-非商业性使用-禁止演绎 3.0 未本地化版本许可协议进行许可。

  • 相关阅读:
    注册表命令大全(二)
    让电脑定时关机
    NSIS nsDialogs 插件
    poj_1562Oil Deposits
    hdoj_1342Lotto
    VS 生成事件文件拷贝
    poj_1111Image Perimeters
    模拟求解迷宫问题(DFS+BFS)
    VS2010如何为所有工程配置环境
    POJ 并查集 题目汇总 ——czyuan原创
  • 原文地址:https://www.cnblogs.com/sweng/p/7089991.html
Copyright © 2020-2023  润新知