В любом современном проекте стоит сразу предусмотреть кеширование данных, будь то файл, memcached или redis.
Хотелось бы узнать как вы кешируете, т.е. в каком месте, что у вас отвечает за кеширование?
Приведу примеры, например кеширование в контролере, часто встречается в простых примерах на многих сайтах.
Каждый раз когда необходимо получить какую-то информацию из модели, проверяется есть ли данные, которые возвращает метод, в кеше, если нет то «дергаем» модель и сохраняем кеш. Ниже привел примерный код.
class Users extends ApplicationModel {
function __construct()
{
}
function getName($id) {
$result = $this->db->execute("SELECT user_name FROM user WHERE id = {$id}");
return $result;
}
}
class UserSettings extends ApplicationController {
function __construct()
{
$user = new Users();
}
function showMainSettings()
{
$key = "UserName_{$id}";
$username = $this->cache->load($key);
if ($username === false) {
$username = $user->getName($id);
$this->cache->save($username, $key);
}
/*
another code and render view
*/
}
}
class UserHome extends ApplicationController {
function __construct()
{
$user = new Users();
}
function showHome()
{
$key = "UserName_{$id}";
$username = $this->cache->load($key);
if ($username === false) {
$username = $user->getName($id);
$this->cache->save($username, $key);
}
/*
another code and render view
*/
}
}
Можно описать кешировние в методах модели. Тогда в контроллере все методы моделей могут вызываться прозрачно.
Приблизительно тот же код будет выглядеть так:
class Users extends ApplicationModel {
function __construct()
{
$this->cache = new Cache();
}
function getName($id) {
$key = "Users_getName_{$id}";
$result = $this->cache->load($key);
if ($result === false) {
$result = $this->db->execute("SELECT user_name FROM user WHERE id = {$id}");
$this->cache->save($result, $key);
}
return $result;
}
}
class UserSettings extends ApplicationController {
function __construct()
{
$user = new Users();
}
function showMainSettings()
{
$username = $user->getName($id);
/*
another code and render view
*/
}
}
class UserHome extends ApplicationController {
function __construct()
{
$user = new Users();
}
function showHome()
{
$username = $user->getName($id);
/*
another code and render view
*/
}
}
И еще один пример который встретил, это использование волшебного метода __call(). В таком случае, все методы пишутся так как будто кеширование не используется. В контроллере можно будет использоваться либо прямой вызов метода $object->method() чтобы гарантированно получить информацию из БД. Также можно будет использовать префикс, что-то вроде $object->cache_method(), в этом случае выполнение метода «обворачивается» в кеш. Ниже еще чуть-чуть кода демонстрирующего данный подход.
class Users extends ApplicationModel {
function __construct()
{
$this->cache = new Cache();
}
function getName($id) {
$result = $this->db->execute("SELECT user_name FROM user WHERE id = {$id}");
return $result;
}
function __call($name,$arguments)
{
$parts = explode('__', $name);
if ('cache'==$parts[0] && method_exists($this,$parts[1]) ) {
$model = get_class($this);
$method = $parts[1];
$arguments_str = md5(serialize($arguments));
$key = "{$model}_{$method}_{$arguments_str}";
$result = $this->cache->load($key);
if($result === false)
{
$result = call_user_func_array(array($this,"{$method}"), $arguments);
$this->cache->save($result,$key);
return $result;
}
else
return $result;
}
else
{
echo "Sorry method not found {$model}::{$method}";
exit(1);
}
}
}
class UserSettings extends ApplicationController {
function __construct()
{
$user = new Users();
}
function showMainSettings()
{
$username = $user->getName($id); // get data from DB
$username_cached = $user->cache__getName($id); // get cached data if exist
/*
another code and render view
*/
}
}
class UserHome extends ApplicationController {
function __construct()
{
$user = new Users();
}
function showHome()
{
$username = $user->getName($id); // get data from DB
$username_cached = $user->cache__getName($id); // get cached data if exist
/*
another code and render view
*/
}
}
Привел три самых распространенных способа которые нашлись в сети. Буду признателен за ссылки на другие да и вообще более продвинутое описание кеширования в/для MVC.
Итак собственно вопрос. Используете ли вы какой-то из этих способов или их модификации и почему именно его? Возможно вы используете что-то более рациональное с точки зрения MVC, поделитесь пожалуйста.
Какой из этих методов или любой другой имеет большее отношение к идеологии MVC?
Заблаговременно спасибо всем тем кто делиться опытом с общественностью!