剛接觸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
咱們以商品詳細頁爲例:
再修改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 ( $filename , strrchr ( $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;?>' . |