从db调用匿名函数

时间:2013-12-05 06:56:16

标签: php yii anonymous-function

我在我的项目中使用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是邪恶的。在这种情况下如何使用匿名函数?

2 个答案:

答案 0 :(得分:1)

不要将代码存储在数据库中。在事件发生后,只有有限数量的事情可以发生,并且这些事件的功能在您的代码库中的某个地方开始。没有必要将它们复制到数据库中,然后尝试从那里评估它们。只需存储您希望在某个事件中发生的事件的标识符(例如sendEmail),然后在您的代码中为该操作调用相应的函数。

关于能够重构代码,这也是非常理智的。想象一下,你必须重写一些会破坏数据库中存储的一百万个回调函数的东西......这不是一个有趣的情况。数据是您的资产,代码就是使这个资产可访问的原因。根据经验,总是保持在你的脑后“如果我用这个项目打击黄金,突然需要扩展到100倍的大小,我雇用一个代理商重写more scalable platform X中的所有内容晚上,我可以继续使用相同的数据吗?“因此数据应该与平台无关。在数据库中存储可执行代码不是。

答案 1 :(得分:0)

你是对的,你应该避免eval

我会使用其他类型的PHP callables,并使用serializebeforeEvent列中对其进行序列化。

然后你可以像你提议的那样打电话给他们:

public function beforeEvent() { call_user_func($this->beforeEvent); }

无法序列化匿名函数。