使用了renderDynamic而没有开启缓存就会出错,能否改一下?

我修改了demo blog的controller post,对action index使用缓存。这样就要在view main里面对UserMenu使用renderDynamic方法了。但是我没有对action admin使用缓存。所以访问action admin的时候renderDynamic就不能把<###dynamic-0###>替换为UserMenu的内容了,而是替换成了其他的缓存的内容。

我又试了一下,把所有的缓存都关了。这时候action admin的&lt;###dynamic-0###&gt;就不被替换成任何内容而直接显示出来。

yii对renderDynamic的处理是否应该修改一下,当找不到它的缓存内容的时候应该直接输出回调函数返回的内容(好像被保存在$this->_dynamicOutput里面了)或者抛出错误,而不应该把<###dynamic-0###>替换成之前其他的缓存内容吧?

调试了很长时间,发现是<###dynamic-$n###>这里的这个$n引起的。$n=count($this->_dynamicOutput);这个视图用到了两次renderDynamic,照说$n应该第一次等于0,第二次等于1了,也就是生成了之前一次<###dynamic-0###>,而UserMenu应该是<###dynamic-1###>。但实际上UserMenu还是<###dynamic-0###>。

这两个renderDynamic分别在layouts column2.php和layouts main.php里面,我把两个renderDynamic都放在layouts main.php里面就没有这个问题了。

能否给renderDynamic增加一个参数,允许手动指定<###dynamic-$n###>的这个$n。这样就可以避免出现这个问题了。

UP :mellow:

我刚刚添加了一个$key参数到renderDynamic()。你能帮忙测试一下么?谢谢。

你那种写法有问题。我改了一下:




	public function renderDynamic($callback,$key=null)

	{

		$params=func_get_args();

		array_shift($params);

		if($key===null || !is_numeric($key))

		{

			$n=count($this->_dynamicOutput);

		}

		else

		{

			$n=$key;

			array_shift($params);

		}

		echo "<###dynamic-$n###>";

		$this->renderDynamicInternal($callback,$params,$n);

	}


	public function renderDynamicInternal($callback,$params,$key)

	{

		$this->recordCachingAction('','renderDynamicInternal',array($callback,$params,$key));

		if(is_string($callback) && method_exists($this,$callback))

			$callback=array($this,$callback);

		$this->_dynamicOutput[$key]=call_user_func_array($callback,$params);

	}



但是还是有问题。我指定的$key是110,它生成的缓存ID是<###dynamic-110###>,但它并没有被替换成UserMenu的内容。而是输出<###dynamic-110###>。我调试发现 processDynamicOutput($output) 的$output始终是空值。不知道是为什么? <_<

刚check in的代码的确有问题,忘记了renderDynamic接受动态参数了。

你能提交一个ticket么?最好能提供一个简单的例子来重现这个问题。多谢了。

我刚才尝试写一个简单例子,但没能重现这个问题。在yii的demo blog里面就能重现。还没搞清楚是什么原因。等我写出一个重现这个问题的例子再提交ticket <_<

Qiang,我发现我上面的判断错了。用两个demo blog改的程序对比。发现一个正常,另外一个的renderDynamic就出问题了。两个的区别仅在layouts column2.php中的一处。

正常的:




<?php $this->beginContent('/layouts/main'); ?>

<div class="container">

	<div class="span-18">

		<div id="content">

			<?php echo $content; ?>

		</div><!-- content -->

	</div>

	<div class="span-6 last">

		<div id="sidebar">

			<?php $this->renderDynamic('widget', 'UserMenu', array('id'=>'user'), true); ?>


			<?php $this->widget('TagCloud', array(

				'maxTags'=>Yii::app()->params['tagCloudCount'],

			)); ?>


			<?php $this->widget('RecentComments', array(

				'maxComments'=>Yii::app()->params['recentCommentCount'],

			)); ?>

		</div><!-- sidebar -->

	</div>

</div>

<?php $this->endContent(); ?>



有问题的:




<?php $this->beginContent('/layouts/main'); ?>

<div class="container">

	<div class="span-18">

		<div id="content">

			<?php echo $content; ?>

		</div><!-- content -->

	</div>

	<div class="span-6 last">

		<div id="sidebar">

			<?php $this->renderDynamic('widget', 'UserMenu', array('id'=>'user'), true);//$this->widget('UserMenu'); ?>


			<?php if($this->beginCache('tagCloud', array('duration'=>99999999, 'dependency'=>array(

        'class'=>'system.caching.dependencies.CDbCacheDependency',

        'sql'=>'SELECT MAX(id) FROM '.Yii::app()->db->tablePrefix.'tag')))) { ?>

			<?php $this->widget('TagCloud', array(

				'maxTags'=>Yii::app()->params['tagCloudCount'],

			)); ?>

			<?php $this->endCache(); } ?>


			<?php $this->widget('RecentComments', array(

				'maxComments'=>Yii::app()->params['recentCommentCount'],

			)); ?>

		</div><!-- sidebar -->

	</div>

</div>

<?php $this->endContent(); ?>



就多了一个,对Tags的缓存。麻烦Qiang解答一下,这个地方有什么问题吗?还需不需要提交ticket?

我刚才又写了一个简单的例子来重现了这个问题。觉得这个地方确实有问题,还是有必要提交一个ticket.

ticket已经提交.Issues 1130

例子也附在下面了,但例子里面没包含yii framework的源码,你要在index里面修改一下包含yii framework的路径再运行。