Widget Cache

Довольно часто возникает необходимость кешировать результат работы виджета, но материала по этой теме мало. Постепенно пришел к такому решению проблемы: создаем класс Widget и наследуем все свои виджеты от него.


class Widget extends CWidget

{

	protected $cacheTime = 3600;

	protected $cacheId = null;

	

	public function init()

	{

		if(!$this->cached())

			$this->generate();

	}

	

	public function generate()

	{

		//$this->render(...);

	}

	

	public function cached()

	{

		if($this->cacheId === null)

			$this->cacheId = 'WidgetCache_' . get_class($this);

		

		$content = Yii::app()->cache->get($this->cacheId);

		

		if($content === false)

			return false;

		

		echo $content;

		return true;

	}

	

	public function render($view, $data = null)

	{

		$content = parent::render($view, $data, true);

		Yii::app()->cache->set($this->cacheId, $content, $this->cacheTime);

		echo $content;

	}

}


class WSample extends Widget

{

	public function generate()

	{

		$this->render('sample');

	}

}


class WSample2 extends Widget

{

	public $param = 2;


	public function init() //У виджета есть параметр, по-этому будет несколько кешей

	{

		$this->cacheId = 'WSample2_' . $this->param;

		$this->cacheTime = 60;


		if(!$this->cached())

			$this->render('sample', $this->param);

	}

}

Я знаю, что есть 2 недостатка:

  1. В методе Widget.generate() для отображения нужно использовать только Widget.render()

  2. Класс только для виджетов, которым не нужен endWidget

Оба недостатка не очень важные, т.к. в моей практики очень редко встречаются. Хотелось бы услышать критику или взглянуть на ваше решение этой проблемы.

P.S. Конечно, самое простое решение, это:


<?php if($this->beginCache($id)){

            $this->widget('...');

            $this->endCache(); } ?>

но мне оно не очень нравится, т.к. при большом количестве виджетов возникает каша, да и править в нескольких местах нестандартное время кеша тоже неудобно.

по этому примеру не сложно реализовать недостатки

Я говорил о недостатках именно моего класса Widget и не говорил, что их сложно устранить. Просто это редкие ситуации в которых проще написать самому реализацию кеша, чем городить один мега-крут-виджет-кеш-класс.