ecmall中的model介紹

以前都是在使用shopex下的ecshop產品,公司項目需要,剛開始接觸ecmall,感覺還是挺像thinkphp框架的模式

  1. //獲取一個模型

  2. function &m($model_name, $params = array(), $is_new = false)

  3. {

  4. static $models = array();

  5. $model_hash = md5($model_name . var_export($params, true));

  6. if ($is_new || !isset($models[$model_hash]))

  7. {

  8. $model_file = ROOT_PATH . '/includes/models/' . $model_name .

  9. '.model.php';

  10. if (!is_file($model_file))

  11. {

  12. /* 不存在該文件,則無法獲取模型 */

  13. return false;

  14. }

  15. include_once($model_file);

  16. $model_name = ucfirst($model_name) . 'Model';

  17. if ($is_new)

  18. {

  19. return new $model_name($params, db());

  20. }

  21. $models[$model_hash] = new $model_name($params, db());

  22. }

  23. return $models[$model_hash];

  24. }

  25. //獲取一個業務模型

  26. function &bm($model_name, $params = array(), $is_new = false)

  27. {

  28. static $models = array();

  29. $model_hash = md5($model_name . var_export($params, true));

  30. if ($is_new || !isset($models[$model_hash]))

  31. {

  32. $model_file = ROOT_PATH . '/includes/models/' . $model_name .

  33. '.model.php';

  34. if (!is_file($model_file))

  35. {

  36. /* 不存在該文件,則無法獲取模型 */

  37. return false;

  38. }

  39. include_once($model_file);

  40. $model_name = ucfirst($model_name) . 'BModel';

  41. if ($is_new)

  42. {

  43. return new $model_name($params, db());

  44. }

  45. $models[$model_hash] = new $model_name($params, db());

  46. }

  47. return $models[$model_hash];

  48. }

複製代碼
所謂模型,則是一個一個的數據實體,換句話說就是一個數據表,你可以基於這個模
型,調用model.base.php中的數據庫操作函數來對數據進行增、刪、改、查的操作。
這裏的業務模型,是在實體模型基礎上,再繼承一次,然後對一些方法進行重寫。
系統中只有三個實體有業務模型:
推薦類型 recommend;商品數據模型 goods;商品分類業務模型 gcategory;
具體操作例子:
//物品表的操作:
$model_goods = & m('goods');
$goods_info = $model_goods->get($goods_id); 這裏需要解釋一下對於數據模型的操作是怎樣的一個函數調用過程:
首先:$model_goods = &m('goods');
我們看一下&m()函數的代碼,其中var_export()函數則是將傳進來的實體,返回相應的實體類對象,因爲所有的model都繼承至model.base.php中的BaseModel類,這個類中定義了基本所有的操作函數,因此$model_goods對象可以對數據庫進行相應的操作。
而我們再看看goods.model.php中的GoodsModel的代碼:

  1. class GoodsModel extends BaseModel

  2. {

  3. var $table = 'goods';

  4. var $prikey = 'goods_id';

  5. var $alias = 'g';//縮寫

  6. var $_name = 'goods';

  7. var $temp; // 臨時變量

  8. var $_relation = array(

  9. // 一個商品對應一條商品統計記錄

  10. 'has_goodsstatistics' => array(

  11. 'model' => 'goodsstatistics',

  12. 'type' => HAS_ONE,

  13. 'foreign_key' => 'goods_id',

  14. 'dependent' => true

  15. ),

  16. // 一個商品對應多個規格

  17. 'has_goodsspec' => array(

  18. 'model' => 'goodsspec',

  19. 'type' => HAS_MANY,

  20. 'foreign_key' => 'goods_id',

  21. 'dependent' => true

  22. ),

  23. // 一個商品對應一個默認規格

  24. 'has_default_spec' => array(

  25. 'model' => 'goodsspec',

  26. 'type' => HAS_ONE,

  27. 'refer_key' => 'default_spec',

  28. 'foreign_key' => 'spec_id',

  29. ),

  30. // 一個商品對應多個屬性

  31. 'has_goodsattr' => array(

  32. 'model' => 'goodsattr',

  33. 'type' => HAS_MANY,

  34. 'foreign_key' => 'goods_id',

  35. 'dependent' => true

  36. ),

  37. // 一個商品對應多個圖片

  38. 'has_goodsimage' => array(

  39. 'model' => 'goodsimage',

  40. 'type' => HAS_MANY,

  41. 'foreign_key' => 'goods_id',

  42. 'dependent' => true

  43. ),

  44. // 一個商品只能屬於一個店鋪

  45. 'belongs_to_store' => array(

  46. 'model' => 'store',

  47. 'type' => BELONGS_TO,

  48. 'foreign_key' => 'store_id',

  49. 'reverse' => 'has_goods',

  50. ),

  51. // 商品和分類是多對多的關係

  52. 'belongs_to_gcategory' => array(

  53. 'model' => 'gcategory',

  54. 'type' => HAS_AND_BELONGS_TO_MANY,

  55. 'middle_table' => 'category_goods',

  56. 'foreign_key' => 'goods_id',

  57. 'reverse' => 'has_goods',

  58. ),

  59. // 商品和會員是多對多的關係(會員收藏商品)

  60. 'be_collect' => array(

  61. 'model' => 'member',

  62. 'type' => HAS_AND_BELONGS_TO_MANY,

  63. 'middle_table' => 'collect',

  64. 'foreign_key' => 'item_id',

  65. 'ext_limit' => array('type' => 'goods'),

  66. 'reverse' => 'collect_goods',

  67. ),

  68. // 商品和推薦類型是多對多的關係 todo

  69. 'be_recommend' => array(

  70. 'model' => 'recommend',

  71. 'type' => HAS_AND_BELONGS_TO_MANY,

  72. 'middle_table' => 'recommended_goods',

  73. 'foreign_key' => 'goods_id',

  74. 'reverse' => 'recommend_goods',

  75. ),

  76. );

  77. var $_autov = array(

  78. 'goods_name' => array(

  79. 'required' => true,

  80. 'filter' => 'trim',

  81. ),

  82. );

  83. }

複製代碼
這裏貼出了實體goods模型類中的內容,先是表格的屬性,再就是goods與其它實體之間的關聯關係的定義。然後我們再看看這個函數,它是BaseModel構造函數裏調用的方法,對對象中的基礎變量進行初使化:

  1. function BaseModel($params, $db)

  2. {

  3. $this->db =& $db;

  4. !$this->alias && $this->alias = $this->table;

  5. $this->_prefix = DB_PREFIX;

  6. $this->table = $this->_prefix . $this->table;

  7. if (!emptyempty($params))

  8. {

  9. foreach ($params as $key => $value)

  10. {

  11. $this->$key = $value;

  12. }

  13. }

  14. }

複製代碼
大家已經看出$_relation 中間是此實體的關聯信息,然後在BaseModel類中的一個函數:

  1. function _getJoinString($relation_info)

  2. {

  3. switch ($relation_info['type'])

  4. {

  5. case HAS_ONE://

  6. $model =& m($relation_info['model']);

  7. /* 聯合限制 */

  8. $ext_limit = '';

  9. $relation_info['ext_limit'] && $ext_limit = ' AND ' . $this->_getExtLimit($relation_info['ext_limit']);

  10. /* 獲取參考鍵,默認是本表主鍵(直接擁有),否則爲間接擁有 */

  11. $refer_key = isset($relation_info['refer_key']) ? $relation_info['refer_key'] : $this->prikey;

  12. /* 本表參考鍵=外表外鍵 */

  13. return " LEFT JOIN {$model->table} {$model->alias} ON {$this->alias}.{$refer_key}={$model->alias}.{$relation_info['foreign_key']}{$ext_limit}";

  14. break;

  15. case BELONGS_TO:

  16. /* 屬於關係與擁有是一個反向的關係 */

  17. $model =& m($relation_info['model']);

  18. $be_related = $model->getRelation($relation_info['reverse']);

  19. if (emptyempty($be_related))

  20. {

  21. /* 沒有找到反向關係 */

  22. $this->_error('no_reverse_be_found', $relation_info['model']);

  23. return '';

  24. }

  25. $ext_limit = '';

  26. !emptyempty($relation_info['ext_limit']) && $ext_limit = ' AND ' . $this->_getExtLimit($relation_info['ext_limit'], $this->alias);

  27. /* 獲取參考鍵,默認是外表主鍵 */

  28. $refer_key = isset($be_related['refer_key']) ? $be_related['refer_key'] :$model->prikey ;

  29. /* 本表外鍵=外表參考鍵 */

  30. return " LEFT JOIN {$model->table} {$model->alias} ON {$this->alias}.{$be_related['foreign_key']} = {$model->alias}.{$refer_key}{$ext_limit}";

  31. break;

  32. case HAS_AND_BELONGS_TO_MANY:

  33. /* 連接中間表,本表主鍵=中間表外鍵 */

  34. $malias = isset($relation_info['alias']) ? $relation_info['alias'] : $relation_info['middle_table'];

  35. $ext_limit = '';

  36. $relation_info['ext_limit'] && $ext_limit = ' AND ' . $this->_getExtLimit($relation_info['ext_limit'], $malias);

  37. return " LEFT JOIN {$this->_prefix}{$relation_info['middle_table']} {$malias} ON {$this->alias}.{$this->prikey} = {$malias}.{$relation_info['foreign_key']}{$ext_limit}";

  38. break;

  39. }

  40. }


  41. /* 模型相關常量定義 */

  42. define('HAS_ONE', 1); //一對一關聯

  43. define('BELONGS_TO', 2); //屬於關聯

  44. define('HAS_MANY', 3); //一對多關聯

  45. define('HAS_AND_BELONGS_TO_MANY', 4); //多對多關聯

  46. define('DROP_CONDITION_TRUNCATE', 'TRUNCATE'); //清空  

複製代碼

從這個函數中,我們可以看到,對於不同的關聯關係,它會返回不同的關聯時的查詢語句片斷,然後連接上主sql語句,就可以針對實體的關聯實體進行相應的關聯操作了。

  1. //物品表的操作:

  2. $model_goods = & m('goods');

  3. $goods_info = $model_goods->find(array(

  4. 'conditions' => "if_show=1 and closed=0",

  5. 'fields' => 'goods_id,goods_name,s.store_id,s.store_name',

  6. 'join' => 'blongs_to_store'

  7. )); 這裏的'join' => 'blongs_to_store' ,我們從上面的:

  8. // 一個商品只能屬於一個店鋪

  9. 'belongs_to_store' => array(

  10. 'model' => 'store',

  11. 'type' => BELONGS_TO,

  12. 'foreign_key' => 'store_id',

  13. 'reverse' => 'has_goods',

  14. ),

複製代碼
這裏我們可以知道這是在與store表進行關聯查找了。ECmall二次開發
到這裏,讀者就可以知道,如果在上面進行二次開發的話,怎樣進行數據庫操作就已經很明確的了。
在BaseModel與cls_mysql(mysql.php)中,有很多的有關數據操作的函數,這裏就不需要再一一進行解釋了,而在cls_mysql中,有一些更基礎的操作函數,還有仿真 Adodb 的函數,可以直接跳過BaseModel中的函數
以上介紹瞭如何在ecmall的平臺上進行數據庫操作,如果操作更加的複雜,這裏還有一種更加直接的方法:

  1. $sql = "select g.goods_id,g.goods_name, from ".DB_PREFIX."goods g, ".DB_PREFIX."goods_spec gs , ".DB_PREFIX."store s where cate_id='".$cate_id."' AND g.if_show = 1 AND g.closed = 0 and g.goods_id=gs.goods_id and g.store_id=s.store_id and gs.stock>0 and s.state=1 order by g.add_time desc limit 6";

  2. $goods_mod =& m('goods');

  3. $category_goods = $goods_mod->getAll($sql);

  4. if(!$category_goods){

  5. $category_goods=array();

  6. }

  7. return $category_goods;

複製代碼
就可以直接使用sql語句進行數據操作了。
還可以在BaseModel中定義自己的操作方法,其中可以使用$this->db->(cls_mysql中定義的方法) 來調用cls_mysql中的函數,從而可以添加更加複雜的數據操作函數。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章