「七天自制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格式輸出,結構一目瞭然,給前端調用也很便利。

相關文章
相關標籤/搜索