ECMall關於數據查詢緩存的問題

剛接觸Ecmall的二次開發不久,接到一個任務。很常見的任務,主要是對數據庫進行一些操做,其中查詢的方法我寫成這樣:php

01 function get_order_data($goods_id)
02 {
03     include_once("gonndb/nmdb.php");
04     include_once("gonndb/dbinfo.php");
05      
06     $connector new nmdb($host$username$password);
07     $connector -> select_db($database);
08  
09     $sql = "select a.buyer_name, a.add_time, a.status, b.phone_tel, b.phone_mob, c.price, c.quantity
10             from shop_order a, shop_order_extm b, shop_order_goods c
11             where a.order_id = b.order_id and b.order_id = c.order_id
12             and c.goods_id = '".$goods_id."'
13             order by a.add_time desc
14             limit 3 ";
15              
16     $result $connector -> query($sql);
17      
18     //$r = array();
19     while($myrow $connector -> fetch_array($result))
20     {
21         $r[] = $myrow;
22     }
23      
24     return $r;
25 }

發現第一次查詢的數據是對的,而後通過模板解析後的數據怎麼都不正確。後來發現,Ecmall有這麼一個機制。先是通過app進行數據庫操做,操做完畢後會在 temp/compileed/ 下留下模板緩存,並且第一次數據庫查詢後會產生數據庫緩存。這壓根就說明,二次開發,最好不要用本身的數據庫函數,用Ecmall自帶的比較好。上面的方法改爲:html

01 function get_order_data($goods_id)
02 {
03     $db = &db();
04      
05     $sql = "select a.buyer_name, a.add_time, a.status, b.phone_tel, b.phone_mob, c.price, c.quantity
06             from shop_order a, shop_order_extm b, shop_order_goods c
07             where a.order_id = b.order_id and b.order_id = c.order_id
08             and c.goods_id = '".$goods_id."'
09             order by a.add_time desc
10             limit 3 ";
11  
12     $result $db -> query($sql);
13      
14     $r array();
15     while($myrow $db -> fetch_array($result))
16     {
17         $r[] = $myrow;
18     }
19      
20     return $r;
21 }

這個函數只是使用了Ecmall自帶的數據庫函數,仍是沒有產生數據庫緩存。看一下別人寫的,如何才能產生數據庫緩存呢?sql

下面是一個公告掛件的程序:數據庫

01 <?php
02  
03 /**
04 * 公告欄掛件
05 *
06 * @param   string  $ad_image_url   廣告圖片地址
07 * @param   string  $ad_link_url    廣告連接地址
08 * @return  array
09 */
10 class NotWidget extends BaseWidget
11 {
12     var $_name 'not';
13     var $_ttl  = 86400;
14     var $_num  = 3;
15  
16     function _get_data()
17     {
18         // 建立一個緩存對象
19         $cache_server =& cache_server();
20         // 獲取該緩存對象數據的id
21         $key $this->_get_cache_id();
22         // 憑證領取對象書記
23         $data $cache_server->get($key);
24         $data1 $cache_server->get($key);
25         if($data === false)
26         {
27             $acategory_mod =& m('acategory');
28             $article_mod =& m('article');
29             $data $article_mod->find(array(
30                 'conditions'    => 'cate_id=' $acategory_mod->get_ACC(ACC_NOTICE) . ' AND if_show = 1',
31                 'order'         => 'sort_order ASC, add_time DESC',
32                 'fields'        => 'article_id, title, add_time',
33                 'limit'         => $this->_num,
34             ));
35             $cache_server->set($key$data$this->_ttl);
36         }
37         if($data1 === false)
38         {
39             $acategory_mod1 =& m('acategory');
40             $article_mod1 =& m('article');
41             $data1 $article_mod1->find(array(
42                 'conditions'    => 'cate_id=' $acategory_mod1->get_ACC(ACC_HELP) . ' AND if_show = 1',
43                 'order'         => 'sort_order ASC, add_time DESC',
44                 'fields'        => 'article_id, title, add_time',
45                 'limit'         => $this->_num,
46             ));
47             $cache_server->set($key$data1$this->_ttl);
48         }
49  
50         return array(
51             'notices'       => $data,
52             'systems'       => $data1,
53         );
54     }
55 }
56  
57 ?>

看了程序,我發現ECMALL的文章調用是這樣的。定義一個data,一堆調用最後經過 ACC_NOTICE 來肯定調用的分類的。最後經過緩存

1 return array(
2     'notices'       => $data,
3 );

來對應一下。網絡

談談寫入數據查詢緩存的步驟:app

1 // 1. 建立緩存對象
2 $cache_server =& cache_server();
3 // 2. 獲取緩存數據的 id
4 $key $this->_get_cache_id();
5 // 自定義也能夠
6 $key 'page_of_goods_' $id;
7 // 將key,數據,緩存時間設置好
8 $cache_server->set($key$data, 1800);

若是是緩存模板文件的話,那就算不使用內存來緩存從數據庫讀取的數據也不要緊,由於最後會把模板文件連同數據一塊兒緩存進一個文件,那後面讀取時就只讀取這個文件而不用再去緩存數據庫,但與靜態化有點不一樣,這個文件裏面還有一點php信息,並不能用來直接輸出,模板引擎會在去掉這點php信息後輸出。frontend

在使用ecmall2時也以爲有時反應不過來,相比來說ecshop還快,通過觀察,其實ecshop在display時是加了一個id的,就是用來緩存此次輸出的。而咱們如今要作的就是在ecmall2裏面實現緩存模板輸出,通俗點講就是在$this->display()時給一個id這個id要惟一。函數

其實全部的東西ecmall2已經準備好了,只是不知道爲何沒有使用,詳細的原理再也不介紹修改完後就可使你的商城在運行方面的速度上一層樓,可是網絡方面可不包哦。fetch

咱們以商品詳細頁爲例:

  1. 修改app/goods.app.php的index方法的最後一行成這樣{$this->display('goods.index.html','goods_detail_'.$id);}(不包括大括號,如下再也不提示)。
  2. app/frontend.base.php文件裏面的class StorebaseApp extends FrontendApp類的function _config_view()方法裏的最後添加以下代碼{$this->_view->cache_dir = ROOT_PATH . "/temp/html_cache/store/{$template_name}";}這裏設置緩存的目錄。
  3. 再找到app/frontend.base.php的class FrontendApp extends ECBaseApp類的function display($tpl)方法的方法名改爲這樣{function display($tpl,$cache_id="")}接着把方法裏面的parent::display($tpl);改爲{parent::display($tpl,$cache_id);}。
  4. 找到includes/ecapp.base.php裏的function display($f)方法的方法名改爲{function display($f,$cache_id="")},以及裏面的parent::display($f);改爲{parent::display($f,$cache_id);}。
  5. eccore/controller/app.base.php裏面的function display($n)方法改爲{function display($n,$cache_id='')},以及裏面的$this->_view->display($n);改{$this->_view->display($n,$cache_id);}。

再修改eccore/view/template.php的function fetch($filename, $cache_id = '')方法以下。

01 function fetch($filename$cache_id '')
02  {
03      if (!$this->_seterror)
04      {
05          error_reporting(E_ALL ^ E_NOTICE);
06      }
07      $this->_seterror++;
08  
09      if (strncmp($filename,'str:', 4) == 0)
10      {
11          $out $this->_eval($this->fetch_str(substr($filename, 4)));
12      }
13      else
14      {
15          if ($this->_checkfile)
16          {
17              if (!is_file($filename))
18              {
19                  $filename $this->template_dir . '/' $filename;
20              }
21          }
22          else
23          {
24              $filename $this->template_dir . '/' $filename;
25          }
26  
27          if ($this->direct_output)
28          {
29              $this->_current_file = $filename;
30              $out $this->_eval($this->fetch_str(file_get_contents($filename)));
31          }
32          else
33          {
34  
35              if ($this->is_cached($filename,$cache_id)&&$cache_id && $this->caching)
36              {
37                  $out $this->template_out;
38              }
39              else
40              {
41                  if (!in_array($filename$this->template))
42                  {
43                      $this->template[] = $filename;
44                  }
45  
46                  $out $this->make_compiled($filename);
47  
48                  if ($cache_id)
49                  {
50                      if ($this->appoint_cache_id)
51                      {
52                          $cachename $cache_id;
53                      }
54                      else
55                      {
56                          $cachename basename($filenamestrrchr($filename'.')) . '_' .$cache_id;
57                      }
58                      $data = serialize(array('template' => $this->template, 'expires' => $this->_nowtime + $this->cache_lifetime, 'maketime' => $this->_nowtime));
59                      $out str_replace("\r"''$out);
60  
61                      while (strpos($out"\n\n") !== false)
62                      {
63                          $out str_replace("\n\n""\n"$out);
64                      }
65  
66                          if (!file_exists($this->cache_dir))
67                                  {
68                                      ecm_mkdir($this->cache_dir);
69                                  }
70  
71                      if (file_put_contents($this->cache_dir . '/' $cachename '.php''<?php exit;?>' 
相關文章
相關標籤/搜索