自制PHP框架之模型关联

自制PHP框架之模型关联

󰅡 技术学院   󰃄 2019-05-22   
转载出处:本文章(教程)为本站原创,未经许可、禁止转载!

前阵子在网上关心一个话题:对于一个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格式输出,结构一目了然,给前端调用也很便利。



精选留言



暂无留言...




󰄫
󰆣
󰆦