记点东西
« »
2012年08月10日PHP

13,099 views

yii绑定onEndRequest事件的bug

yii在CListIterator中使用引用,导致迭代在特殊情况下会出现BUG

1
2
3
4
5
6
7
8
9
10
11
public function actionIndex()
{
    $data = array('a', 'b', 'c');
    $a = new CList($data);
    foreach ($a as $k => $v) {
        if ($k == 0) {
            unset($a[0]);
        }
        echo $v;
    }
}

如果预先不知道这个情况,很容易出现问题,框架中也有这个问题,看一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public function setGlobalState($key,$value,$defaultValue=null)
{
    // ...
 
    if($this->_stateChanged!==$changed)
        $this->attachEventHandler('onEndRequest',array($this,'saveGlobalState'));
}
 
// ...
 
/**
* Saves the global state data into persistent storage.
* @see getStatePersister
* @throws CException if the state persister is not available
*/
public function saveGlobalState()
{
    if($this->_stateChanged)
    {
        $this->_stateChanged=false;
        $this->detachEventHandler('onEndRequest',array($this,'saveGlobalState'));
        $this->getStatePersister()->save($this->_globalState);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
public function raiseEvent($name,$event)
{
    $name=strtolower($name);
    if(isset($this->_e[$name]))
    {
        foreach($this->_e[$name] as $handler)
        {
            // ...
        }
    }
    // ...
}

当runtime目录被清空时,onEndRequest事件触发saveGlobalState动作,在操作的过程中却又解除了saveGlobalState动作的绑定。这会导致raiseEvent事件的时候,原来N个动作变成N-1个动作,但是计算器还是N个,就会下标越界。

向官方提交了这个BUG,想修正的话可以先注释掉这行:

1
    $this->detachEventHandler('onEndRequest',array($this,'saveGlobalState'));

日志信息 »

该日志于2012-08-10 14:22由 yuehei 发表在PHP分类下, 你可以发表评论。除了可以将这个日志以保留源地址及作者的情况下引用到你的网站或博客,还可以通过RSS 2.0订阅这个日志的所有评论。

相关日志 »

没有评论

发表评论 »

返回顶部