Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [ZendFramework]Cache dla zapytań
Forum PHP.pl > Forum > PHP > Frameworki
Eagle
Witam

Szukałem ostatnio jak ładnie("Zendowo" smile.gif) zrobić cache dla wyników z bazy, jednak nic nie znalazłem.
Wpadłem na pomysł aby zrobić klasę (abstract) która będzie zarządzać całością.

Obrazowo

Klasa która zarządza cache
  1. abstract class cacheDlaSql
  2. {
  3. protected $_cache = null;
  4. protected $_db;
  5.  
  6. public function __construct($db,$cache=null)
  7. {
  8. $this->_db = $db;
  9. if(isinstanceof(Zend_Cache....))
  10. $this->_cache = $cache;
  11. }
  12.  
  13. protected _query(Zend_Db_Select $select, $typ = 'fetchAll')
  14. {
  15. if($_cache)
  16. {
  17. $cacheName = md5($select->assemble());
  18. //Jest cache
  19. //
  20. }
  21. else
  22. {
  23. // Brak cache
  24. // Normalne zapytanie
  25. }
  26.  
  27. // Inne funkcje (kasowanie etc.)
  28. }


Zwykła klasa
  1. class Portal_Newsy extends cacheDlaSql
  2. {
  3. public function dajMiNewsa($id)
  4. {
  5. $select = $this->_db->select()
  6. ->from(....);
  7.  
  8. return $this->_query($select);
  9. }
  10. }


Co myślicie o takim rozwiązaniu ?

Pozdrawiam
pgrzelka
mi się wydaje że lepiej pozostać przy standardowym rozwiązaniu zenda, sam je stosuje i nigdy nie ma problemu
  1. class Model_Newsy extends Zend_Db_Table {
  2. protected $_name = 'newsy';
  3.  
  4. public function dajMiNewsa($id) {
  5. $cache = Zend_Registry::get('cache'); // tu mamy cache zdefiniowane w bootstrapie
  6. if ($news = $cache->load('news_'.$id) {
  7. $news = $this->find($id)->current();
  8. $cache -> save($news, 'news_'.$id);
  9. }
  10. return $news;
  11. }
  12.  
  13. }


jeśli jednak postanowisz dalej kontynuować tworzenie własnej klasy to uwzględnij fakt że nie każde zapytanie powinno być cachowane
ActivePlayer
ja również uważam ze klasyczne użycie zend_cache jest lepsze. Kiedyś starałem się napisać obszerną klasę do cachowania wsystkiego co leciało z bazy. W praktyce zabrakło tam takiej logiki jak uwzględnienie "NOW()", "RAND()" w zapytaniach i założenie poległo.

Dużo lepiej jest cachować dane, dopiero w sytuacji gdy wymaga tego sytuacja. Zend_Cache nadaje się do tego idealnie. W momencie kiedy aplikacja pokazuje wąskie gardło, w którejś swojej części, to za nią zabieramy się, odpowiednio cachując dane. Pamiętaj żeby nie optymalizować tego, co nie sprawia problemów.
Eagle
Może niejasno wyraziłem się w poprzednim poście.

Zend_Db_Table jeszcze nie używam (nie znalazłem dobrego przykładu, który by mi dokładnie wytłumaczył tongue.gif)

Oczywiście używam Zend_Cache, tylko chodzi mi o sposób w jaki to robie:

  1. /**
  2. * @category Portal
  3. * @package Portal_News
  4. */
  5. class Portal_News extends Aquila_Model_Cache_MySql implements Portal_News_Interface
  6. {
  7. /**
  8. * Zwraca informacje o konkretnym newsie
  9. *
  10. * @param int $newsId
  11. * @param array $options
  12. * @return array
  13. */
  14. public function getId($newsId,array $options = array())
  15. {
  16. $newsId = (int)$newsId;
  17.  
  18. $query = $this->_db->select()
  19. ->from(array('n'=>'news'),'n_date')
  20. ->joinLeft(array('nt' => 'newstext'),'nt.n_id = n.n_id',array('nt_title','nt_text'))
  21. ->joinLeft(array('m' => 'members'),'m.m_id = n.m_id',array('m_id','m_name'))
  22. ->where('n.n_id = ?', $newsId)
  23. ->limit(1);
  24.  
  25. if(array_key_exists('language', $options))
  26. $query->where('nt.l_id = ?', $options['language']);
  27.  
  28. return $this->_select($query,'fetchRow');
  29. }
  30. }


Klasa "obsługi" cache
  1. abstract class Aquila_Model_Cache_MySql
  2. {
  3. /**
  4. * @var Zend_Db_Adapter_Pdo_Abstract
  5. */
  6. protected $_db;
  7.  
  8. /**
  9. * @var Zend_Cache_Core
  10. */
  11. protected $_cache;
  12.  
  13. /**
  14. * Konstruktor
  15. *
  16. * @param Zend_Db_Adapter $db
  17. * @param Zend_Cache_Adapter $cache
  18. * @return Aquila_Model_Cache
  19. */
  20. public function __construct(Zend_Db_Adapter_Pdo_Abstract $db, Zend_Cache_Core $cache = null)
  21. {
  22. $this->_db = $db;
  23. $this->_cache = $cache;
  24. }
  25.  
  26. /**
  27. * Zapytanie
  28. *
  29. * @param Zend_Db_Select $select
  30. * @param string $fetchMode
  31. * @param array $options
  32. * @return array
  33. */
  34. protected function _select(Zend_Db_Select $select, $fetchMode = 'fetchAll', array $options = array())
  35. {
  36. if($this->_cache)
  37. {
  38. $cacheName = md5($select->assemble());
  39.  
  40. if($data = $this->_cache->load($cacheName))
  41. {
  42. return $data;
  43. }
  44. }
  45.  
  46.  
  47. switch($fetchMode)
  48. {
  49. case 'fetchAssoc':
  50. $data = $this->_db->fetchAssoc($select);
  51. break;
  52.  
  53. case 'fetchCol':
  54. $data = $this->_db->fetchCol($select);
  55. break;
  56.  
  57. case 'fetchfetchOne':
  58. $data = $this->_db->fetchOne($select);
  59. break;
  60.  
  61. case 'fetchPairs':
  62. $data = $this->_db->fetchPairs($select);
  63. break;
  64.  
  65. case 'fetchRow':
  66. $data = $this->_db->fetchRow($select);
  67. break;
  68.  
  69. case 'fetchAll':
  70. default:
  71. $data = $this->_db->fetchAll($select);
  72. break;
  73. }
  74.  
  75. if($this->_cache)
  76. {
  77. $this->_cache->save($data, $cacheName);
  78. }
  79.  
  80. return $data;
  81. }
  82. }


Jeżeli zapytanie zapisuje wynik do cache to używam funkcji _select.
Zapytania bez cache, wywołuje bezpośrednio $this->_db->fetch...()

Pozdrawiam.
pc3t
Polecam przeczytać to:
http://www.contentwithstyle.co.uk/content/...tern-for-models
Ciekawy sposób dorzucenia cache do modelu.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.