我在我的项目中使用Yii并希望通过回调实现事件模型。我在MySQL中制作了“事件”模型,并希望在许多领域中存储匿名函数,例如,
**Event model in Yii**
id - int
name - varchar(255)
beforeEvent - text
在“afterEvent”字段中存储函数:
function(){echo 'afterEvent #1';}
然后我获取所有事件并尝试调用“afterEvent”函数:
$events = Event::model()->findAll();
foreach ($events as $event)
{
$event->beforeEvent();
}
由于我在模型事件中没有那个方法,我做了代理方法
public function beforeEvent() { call_user_func($this->beforeEvent); }
出错的问题:
call_user_func()期望参数1是有效的回调函数 'function(){echo'after事件#1完成后'; ''找不到或 功能名称无效
找到 1解决方案: 在proxy-method beforeEvent()中使用 create_function 这样的函数:
public function beforeEvent(array $params){
$callback = create_function('$params', $this->beforeEvent);
$callback($params);
}
但在手册中说:
此函数在内部执行eval(),因此具有相同的功能 安全性问题如eval()。此外,它有糟糕的表现和 内存使用特性。如果您使用的是PHP 5.3.0或更高版本的a 应该使用原生匿名函数。
我们认为eval是邪恶的。在这种情况下如何使用匿名函数?
答案 0 :(得分:1)
不要将代码存储在数据库中。在事件发生后,只有有限数量的事情可以发生,并且这些事件的功能在您的代码库中的某个地方开始。没有必要将它们复制到数据库中,然后尝试从那里评估它们。只需存储您希望在某个事件中发生的事件的标识符(例如sendEmail
),然后在您的代码中为该操作调用相应的函数。
关于能够重构代码,这也是非常理智的。想象一下,你必须重写一些会破坏数据库中存储的一百万个回调函数的东西......这不是一个有趣的情况。数据是您的资产,代码就是使这个资产可访问的原因。根据经验,总是保持在你的脑后“如果我用这个项目打击黄金,突然需要扩展到100倍的大小,我雇用一个代理商重写more scalable platform X
中的所有内容晚上,我可以继续使用相同的数据吗?“因此数据应该与平台无关。在数据库中存储可执行代码不是。
答案 1 :(得分:0)