Thứ Sáu, 1 tháng 6, 2012

Zend Framework: Tìm hiểu và sử dụng Zend_Cache

Chào mọi người,
Đây là lần đầu tiên mình viết tutorial để chia sẻ kiến thức mình nghiên cứu được về Zend Cache, nếu có sai sót rất mong sự góp ý của mọi người ^^

Khái quát về kỹ thuật catching:
Caching là kỹ thuật lưu lại nội dung những trang web được duyệt, kết quả truy vấn cơ sở dữ liệu,… vào tập tin (file), bộ nhớ đệm (memcache)… để có thể tái sử dụng nhiều lần.

Để tiện cho việc truy xuất sau khi cache, mỗi thành phần được cache sẽ có một ID để định danh.
Việc sử dụng cache sẽ làm tăng tốc ứng dụng đáng kể.



Ví dụ (cache kết quả truy vấn CSDL):

Ta có một menu bao gồm: Trang chủ, Văn hóa, Giáo dục,… được lưu trong cơ sở dữ liệu.

Khi không thực hiện cache, mỗi khi người dùng muốn load menu đó ra thì ứng dụng sẽ phải thực hiện tuần tự các bước sau: kết nối CSDL, thực hiện câu truy vấn, trả kết quả về và cuối cùng là load ra cho người sử dụng. Hãy tưởng tượng 100, 1000 người dùng kết nối và load menu đó cùng lúc thì vấn đề gì sẽ xảy ra? Máy chủ CSDL sẽ hoạt động thực hiện câu truy vấn 100, 1000 lần để load menu cho 100, 1000 người dùng.

Khi thực hiện cache: Ứng dụng sẽ chỉ phải thực hiện các bước như trên (kết nối CSDL, thực hiện truy vấn,..) một lần duy nhất và lưu vào cache (file, RAM) với một định danh. Lần sau, khi người dùng muốn load menu đó thì ứng dụng sẽ truy cập vào cache (file, RAM) và lấy ra kết quả.

Phân loại cache trong Zend_Cache:
  • frontEnd: cache các đối tượng như:
    • Output: cache tất cả mọi thứ giữa phương thức start() và phương thức end()
    • Function: cache kết quả của việc gọi phương thức sử dụng phương thức call() để lấy tên phương thức và các tham số của phương thức.
    • File: cache kết quả ra file
    • Page: cache toàn bộ một trang web
  • backEnd: các kiểu cache như:
    • File: lưu ra file
    • Memcached: lưu trên RAM
Các bạn có thể tham khảo thêm các đối tượng cache và các kiểu cache tại đây
Mã:
framework.zend.com/manual/en/zend.cache.frontends.html
framework.zend.com/manual/en/zend.cache.backends.html
Khởi tạo:

Ta sử dụng phương thức sau:
PHP Code:
$cache=Zend_Cache::factory(‘frontend_cache_type’,backend_cache_type’,frontendParam,backendParam);  
Trong đó:
Frontend_cache_type: kiểu cache đối tượng
Backend_cache_type: kiểu cache backend
FrontendParam: các thông số của frontend
BackendParam: các thông số của backend

Ví dụ sau đây ta khởi tạo một đối tượng $cache với cache frontend là Core, cache backend là File cùng các thông số tương ứng.

Đầu tiên, trong file index.php ta khai báo thêm thông số:
PHP Code:
define('CACHE_DIR',APPLICATION_PATH.'/cache/');  
khai báo trên định nghĩa hằng tên là CACHE_DIR và giá trị tương ứng của nó (thư mục chứ tập tin cache)

Tiếp theo ta tạo thư mục /applicaton/cache

Khởi tạo cache trong controller (ví dụ ở đây là IndexController.php)
PHP Code:
<?phpclass IndexController extends Zend_Controller_Action{
    public function 
indexAction(){
        
$frontendParam=array(
            
‘lifetime’=>3600,        //thời gian tồn tại của cache, giá trị null nghĩa là thời gian tồn tại vô hạn
            
‘automatic_serialization’=>‘true’ //cho phép tự động serialize với các kiểu dữ liệu phức tạp
        
);
        
$backendParam=array(
            
‘cache_dir’=>CACHE_DIR    //chỉ định vị trí thư mục cache
        
);
        
$cache=Zend_Cache::factory(‘Core’,’File’,$frontendParam,$backendParam);//khởi tạo một đối tượng $cache với cache frontend là Core, cache backend là File cùng các thông số tương ứng
    
}
}
Ta đã khởi tạo được đối tượng cache, vậy sử dụng chúng như thế nào?

Cũng trong file indexController.php, ta tạo một cache ID
PHP Code:
$cache_id=’list_user’;  
Muốn lưu dữ liệu vào cache ta thực hiện
PHP Code:
$cache->save($data,$cache_id)  
Ở đây $data là dữ liệu mà chúng ta muốn lưu vào cache

Muốn load dữ liệu từ cache ra để sử dụng ta thực hiện
PHP Code:
$cache->load($cache_id);  
Muốn xóa dữ liệu trong cache ta thực hiện
PHP Code:
$cache->remove($cache_id)  
Cache Manager:
Một ứng dụng có thể cần nhiều kiểu cache khác nhau. Nếu chúng ta sử dụng cache trong các controller thì không được tối ưu (khai báo mỗi khi sử dụng) và việc sử dụng lại các kiểu cache đó trong các controller khác khá khó khăn.

Do đó, Cache Manager (khai báo trong file bootstrap) được sử dụng để quản lý các kiểu cache trong ứng dụng đồng thời làm cho việc sử dụng cache trong các phần khác nhau của ứng dụng trở nên dễ dàng hơn.

Cache Manager quản lý các kiểu cache bằng các template (mẫu).

Trong file bootstrap.php, ta khởi tạo phương thức _initCachemanager() và khai báo một đối tượng Zend_Cache_Manager để quản lý.

Tiếp theo, ta khai báo biến chứa các thông số cache frontEnd, backEnd dưới dạng mảng.
PHP Code:
<?phpclass Bootstrap extends Zend_Application_Bootstrap_Bootstrap{
protected function 
_initCachemanager(){
    
$cacheManager=new Zend_Cache_Manager;
        
$dbcache=array(            //bắt đầu khai báo template
            
'frontend'=>array(
                
'name'=>'Core',
                
'options'=>array(
                    
'lifetime'=>null,
                    
'automatic_serialization'=>'true',
                ),
            ),
            
'backend'=>array(
                
'name'=>'File',
                
'options'=>array(
                    
'cache_dir'=>CACHE_DIR,
                ),
            ),
        );                    
//kết thúc khai báo template
        
$cacheManager->setCacheTemplate('dbcache',$dbcache); //gán template $dbcache với tên là dbcache
        
return $cacheManager;
    }
}
Phương thức setCacheTemplate sẽ gán một biến chứa các thông số cache (bao gồm frontEnd và backEnd) vào một template có tên là dbcache.

Tương tự, chúng ta có thể khai báo tiếp các biến khác chứa các thông số cache mà chúng ta muốn sử dụng và dùng hàm setCacheTemplate để gán vào một template khác.

Như vậy đối tượng cacheManager sẽ quản lý tất cả các cacheTemplate được khai báo trong phương thức _initCachemanager().

Sử dụng: 

Việc gọi sử dụng các kiểu cache trong các phần khác nhau của ứng dụng rất đơn giản. Chúng ta chỉ cần sử dụng câu lệnh sau:
PHP Code:
$cache=$this->getInvokeArg(‘bootstrap’)->getResource(‘Cachemanager’)->getCache(‘dbcache’);  
Câu lệnh này sẽ truy cập vào file bootstrap.php, lấy ra đối tượng Cachemanager và lấy template tên là dbcache để sử dụng.

Code đầy đủ như sau:
File Bootstrap.php:
PHP Code:
<?phpclass Bootstrap extends Zend_Application_Bootstrap_Bootstrap{
    protected function 
_initCachemanager(){
        
$cacheManager=new Zend_Cache_Manager;
        
$dbcache=array(
            
'frontend'=>array(
                
'name'=>'Core',
                
'options'=>array(
                    
'lifetime'=>null,
                    
'automatic_serialization'=>'true',
                ),
            ),
            
'backend'=>array(
                
'name'=>'File',
                
'options'=>array(
                    
'cache_dir'=>CACHE_DIR,
                ),
            ),
        );
        
$cacheManager->setCacheTemplate('dbcache',$dbcache);
        return 
$cacheManager;
    }
}
File IndexController.php:
PHP Code:
<?phpclass IndexController extends Zend_Controller_Action{
    public function 
listAction(){
        
$dbcache=$this->getInvokeArg('bootstrap')->getResource('cachemanager')->getCache('dbcache');
        
$id='list_cache';
        if(!
$dbcache->load($id)){
            
$muser=new Model_User;
            
$data=$muser->listall();
            
$dbcache->save($data,$id);
            
$this->view->data=$dbcache->load($id);     
        }
        
$this->view->data=$dbcache->load($id);
    }
}
Đoạn code này có nghĩa là nếu không load được nội dung cache trong cache ID có tên là list_cache thì sẽ tiến hành kết nối CSDL để lấy ra kết quả sau đó lưu vào cache có ID là list_cache, nếu load được nội dung trong cache ID thì không cần tiến hành kết nối CSDL

File User.php:
PHP Code:
<?phpclass Model_User extends Zend_Db_Table_Abstract{
    protected 
$_name="user";
    protected 
$_primary="id";
    public function 
listall(){
        return 
$this->fetchAll()->toArray();
    }
Chạy ứng dụng, sau đó ngắt kết nối CSDL và xem kết quả.
Bạn cũng có thể truy cập vào đường dẫn application/cache để xem cấu trúc của file cache :)
Chúc mọi người thành công :)

1 nhận xét: