2015年1月5日 星期一

MyMVC - Model

不小心把程式碼更新太快,來不及寫這篇文orz


現在已經處理完control 和 view,再來就是把缺的那個主角給補上 - Model

以上次的結構圖來說,Model是接合在coltrol底下的,而我們又不可能每次都要建一個模版給Model用,所以再來就是建立一個Model Lib Class啦~


首先,我們要先了解一個關於DataBase的基礎結構(不是語法哦~)

1.DataBase 的連結
2.語法的組合 Function
3.語法的輸入、輸出

就這個主體為DataBase Lib Class的組合
首先到了修改load.php這隻程式
<?php
if(!isset($_SESSION))
session_start();
$UrlBase = explode('load.php',$_SERVER['PHP_SELF']);
if(!isset($_SESSION['SiteUrl'])){
$port = ($_SERVER['SERVER_PORT'] == 80)?'http://':'https://';
$_SESSION['SiteUrl'] = $port . $_SERVER['HTTP_HOST'] . $UrlBase[0];
}
$url = explode('/',$UrlBase[1]);
$url = array();
foreach(explode('/',$UrlBase[1]) as $val){
if($val != '')
$url[] = $val;
}
/*set data base info*/
$DbType = 'mysql';
$DbHost = '127.0.0.1';
$DbUser = 'root';
$DbPw = '';
$DbName = 'framwork_exp';

define('DbType', $DbType);
define('DbHost', $DbHost);
define('DbUser', $DbUser);
define('DbPw', $DbPw);
define('DbName', $DbName);
/*set data base info*/

include 'lib/LibDataBase.php';
include 'lib/LibBoot.php';
$boot = new LibBoot($url);

加上資料庫的類型(基本上是使用所MySQL)、資料庫URL、帳號、密碼、資料庫名稱
這樣會在連線時就設定完了

再來下方的 LibDataBase.php這個是所謂的Model的母版(也就是上面所說的:DataBase Lib Class),是放在lib資料夾底下。
所有的Model Class都會繼承這個母版,所以先在這裡把他給載入。

接下來在根目錄下建立model這個資料夾,所有的Model Class都是放在這裡的。

在lib資料夾中,新增一隻叫LibDataBase,php程式吧(在這是使用我自行設計的DataBase Lib Class,也可以使用自己習慣的)
<?php
class LibDataBase {
public $dbtype, $dbhost,$dbuser,$dbpass,$dbname,$table;
public $count = 0;
public $install = false;

//共用function
function __construct() {
$this->dbtype = DbType;
if ($this->dbtype == 'mysql') {
if($this->CheckDataBaseLink(DbHost,3306)){
$this->dbhost = DbHost;
$this->dbuser = DbUser;
$this->dbpass = DbPw;
$this->dbname = DbName;
}else{
echo 'DB link is false.';
exit;
}
}
if ($this->dbtype == 'sqlite') {
$this->dbname = DbName;
}
}

public function Link() {
/*test link add by Sam 20140805*/
$link = false;
if ($this->dbtype == 'mysql'){
$link = new PDO(
"mysql:host=$this->dbhost;dbname=$this->dbname",
$this->dbuser,
$this->dbpass,
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING,
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
)
);
}
if ($this->dbtype == 'sqlite') {
$link = new PDO("sqlite:" . $this->dbname);
if (!$link) die ($error);
}
/*test link add by Sam 20140805*/
if($link)
return $link;
else{
echo 'DB link is false.';
exit;
}
}

//測試連線
private function CheckDataBaseLink($host, $port) {
$ch_ini_display = (ini_get('display_errors') == 1);
if ($ch_ini_display) //判斷ini的display errors的設定
ini_set('display_errors', 0); //設定連線錯誤時不要display errors
$x = fsockopen(gethostbyname($host), $port, $errno, $errstr, 1);
if ($ch_ini_display)
ini_set('display_errors', 1); //將ini的display error設定改回來
if (!$x)//測試連線
return false;
else {
fclose($x);
return true;
}
}
//共用function end
//語法組合

public function Select($table, $field, $req = false, $other = false) {
$table = $this->comb(',',$table);
$field = $this->comb(',', $field);
$req = ($req)?'where ' . $req:'';
$or_by = '';
$limit = '';
if($other){
$or_by = (isset($other['order_by']))?" order by " . $this->comb(',',$other['order_by']):'';
$limit = (isset($other['limit']))?" limit " . $other['limit']:'';
}
$sql = "select $field from $table $req $or_by $limit;";
return $sql;
}

public function In($table, $arr) {
$field = '(' . $this->comb(',',array_keys($arr)). ')';
$value = "(" . $this->comb(',',$this->ValAddTip(array_values($arr))) . ')';

$sql = "insert into $table $field values $value;";
return $sql;
}

public function Del($table, $req = '') {
//DELETE FROM [TABLE NAME] WHERE 條件;
$table = $this->comb(',',$table);
if ($req != '')
$req = 'where ' . $req;
$sql = "DELETE FROM $table $req;";
return $sql;
}

public function Up($table, $arr, $req = '') {
//UPDATE [TABLE NAME] SET [欄名1]=值1, [欄名2]=值2, …… WHERE 條件;
foreach($arr as $key => $value){
$toV[] = "`$key`='$value'";
}
$value = $this->comb(",",$toV);
$req = ($req != '')?' where ' . $req:'';
$sql = "update $table set $value$req;";
return $sql;
}
//語法組合 end
//sql執行
public function Query($sql = flase) {
if($sql){
$link = $this->Link();
$link->query($sql);
$link = null;
}
}

public function Fetch($sql) {
$link = $this->Link();
$this->count = 0;
$query = $link->query($sql);
$this->count = count($query);
$query = $query->fetchAll();
$link = null;
return $this->ValDecode(query);
}

public function Assoc($sql, $field = false, $req = false, $other = false) {
if($field){
$sql = $this->Select($sql,$field, $req, $other);
}
$link = $this->Link();
$re = $link->query($sql);
$re->setFetchMode(PDO::FETCH_ASSOC);
$re = $re->fetchAll();
$this->count = count($re);
$link = null;
return $this->ValDecode($re);
}
//sql執行

/*共用函式*/
public function ValAddTip($arr,$tip="'"){
if(!is_array($arr))
return $tip.$arr.$tip;
foreach($arr as $key =>$value){
$arr[$key] = "$tip$value$tip";
}
return $arr;
}

protected function comb($sub2,$arr) {
$re = false;
if (is_array($arr)) {
$re = implode($sub2,array_values($arr));
} else {
$re = $arr;
}
return $re;
}

protected function combTip($arr) {
foreach($arr as $key => $value){
$arr[$key] = '('.implode(',',$this->ValAddTip($value)).')';
}
return implode(',',$arr);
}

public function ValDecode($arr){
if(is_array($arr)){
foreach($arr as $key2 => $value2)
$arr[$key2] = $this->ValDecode($value2);
}else{
$arr = str_replace(array('@&4', '@&3', '@&2', '@&1', '@&5'), array(">", "<", '"', "'", "&"), stripslashes($arr));
}
return $arr;
}

public function Json2Array($json) {
$ret = array();
foreach($json as $key => $val){
$ret[$key] = (is_object($val) or is_array($val))?$this->Json2Array($val):$val;
}
return $ret;
}
/*共用函式*/
}

接下來就可開始寫model的clss了
假設,我們目前我們所撰寫的是留言板,那我們就需要設計一個留言板的Table,在此暫稱為flow吧
CREATE TABLE `flow` (
`seq` INT(11) NOT NULL,
`name` TEXT NOT NULL COLLATE 'utf8_unicode_ci',
`content` LONGTEXT NOT NULL COLLATE 'utf8_unicode_ci',
`rebk` INT(11) NULL DEFAULT NULL,
`date` VARCHAR(20) NOT NULL COLLATE 'utf8_unicode_ci',
PRIMARY KEY (`seq`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB;

這張表中分別記錄著 seq(流水號),name(留言者的名字),content(內文),rebk(回覆哪篇),Date(留言時間)

然後在model裡新增一隻叫做index.php的程式,這隻程式就是處理有關index的所有關於資料庫的資料(在此是以頁面取向,也可以以功能取向,ex:flow.php)

再來就是修改 control/index.php
<?php
class index {
private $db;
function __construct(){
include 'model/index.php';
$this->db = new ModelIndex;
}
/*載入index頁面所用的function*/
public function index($arr = false){
if(isset($arr['post'])){
$arr = $arr['post'];
}
if(!$arr){

}
}
}

接下來,就是在model中新增一隻叫index.php

<?php
class ModelIndex extends LibDataBase {
private $Table;
private $row = 50;
function __construct() {
parent::__construct();
$this->Table = 'flow';
}

public function GetFlow($arr=false){
$toDb['R'] = array();
$toDb['F'] = (isset($arr['F']) and $arr['F'] != '')?$arr['F']:'*';
if(isset($arr['R'])){
$arr['R'] = $this->ValAddTip($arr['R']);
foreach($arr['R'] as $key => $val){
$toDb['R'][] = "$key = $val";
}
}

$toDb['R'][] = "(rebk is null or rebk ='')";
$toDb['R'] = implode(' and ', $toDb['R']);

$tmp = $this->Assoc($this->Table, '*',$toDb['R'], array('order_by'=>'seq desc'));
if(count($tmp)!=0){
$re['page']['count'] = count($tmp);
$re['page']['row'] = $this->row;
$re['page']['page']= (isset($arr['page']))?$arr['page']+1:1;
$i = 1;
foreach($tmp as $val){
$val['content']=nl2br(str_replace(array('<','>'),array('&lt;','&gt;'),$val['content']));
$re['data'][$i][] = $val;
if(count($re['data'][$i]) % $this->row == 0){
$i++;
}
}
if(isset($re['data'][$re['page']['page']])){
$re['data'] = $re['data'][$re['page']['page']];

$tmp ='';
foreach($re['data'] as $val){
$tmp .= ($tmp != '')?','.$val['seq']:$val['seq'];
}
$tmp = $this->Assoc($this->Table, $toDb['F'], "rebk in ($tmp)", array('order_by'=>'seq desc'));
foreach($tmp as $key =>$val)
$tmp[$key]['content']=nl2br(str_replace(array('<','>'),array('&lt;','&gt;'),$tmp[$key]['content']));
$re['data'] = array_merge($re['data'], $tmp);
return $re;
}else{
return false;
}
}else{
return false;
}
}

public function SaveFlow($arr = false){
if($arr){
//$arr['content'] = $this->ValEncode(nl2br(urlencode($arr['content'])));
$arr['date'] = date('Y-m-d H:i:s');
if($arr['id'] != 0)
$arr['rebk'] = $arr['id'];
unset($arr['id']);
$sql=$this->In($this->Table,$arr);
$this->Query($sql);
return true;
}else{
return false;
}
}
}


這樣就可以直接在control裡控制取得資料了

而在取得資料後,可以經由LibBoot.php這隻程式,將處理完的資料回傳給view裡,使用的方式就是在HTML直接使用一個叫做$InData的變數
ex:

<?php
print_r($InData);
?>

詳細的設計方式可以直接到github裡看我的那個例子

沒有留言:

張貼留言