我应该使用 eval() 还是 call_user_func()?
我正在开发一个 php 项目,我想运行从 MySQL 数据库获取的代码。 不安全代码不可能被注入,所以我唯一担心的是性能。 我应该使用 eval() 以便直接运行代码,还是解析它以便 call_user_func() 运行它?
例如,如果我获取的代码是“myfunc(1,2,3); anotherFunc(3,2,1);”
我可以直接 eval() 来运行代码。
但对于 call_user_func(),我必须解析字符串才能运行它。 那么在这种情况下使用哪个函数更好呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
将 PHP 存储在数据库中本身就是一种糟糕的设计味道; 即使在这种情况下,您非常确定它永远不会包含不安全的代码,但尽量减少您必须做出的假设或防御的数量总是好的。 如果您将 PHP 代码存储在数据库中,那么攻击者访问您的数据库的攻击很快就会变得更加严重,变成攻击者可以运行任意代码的攻击! 我知道您的数据库像这样受到损害的可能性极小,但尽管如此,即使是不太可能的情况,也不要让您的系统受到不必要的损害,这是一种良好的安全实践。
许多人同意 eval() 应该始终,无一例外,在 PHP 代码中应避免使用。 总有一个替代方案。
然而,在这种情况下,我认为我不得不说使用 eval() 将是您的最佳解决方案,因为您已经将 PHP 代码存储在数据库中,因此使用 eval() 不会增加您的风险除此之外。
但是,我建议
如果这个答案看起来有点反动,我很抱歉; 我只是碰巧觉得这种事情非常重要。
Storing PHP in the database is a bad design smell in itself; even though in this case you are pretty sure it can never contain unsafe code, it is always good to minimize the number of assumptions or defenses like that you have to make. If you store PHP code in the database, then an attack in which an attacker gains access to your database quickly becomes a lot more serious, turning into an attack in which an attacker can run arbitrary code! I know that having your database compromised like this is highly unlikely, but nonetheless it is good security practice not to let even an unlikely situation compromise your system more than it needs to.
Many people agree that eval() should always, without exception, be avoided in PHP code. There's always an alternative.
In this case, however, I think that I would have to say that using eval() would be the best solution for you, because you are already storing PHP code in the DB, so using eval() is not going to increase your risk any further than that.
I would, however, recommend that
I'm sorry if this answer seems a bit reactionary; I just happen to feel this sort of thing is very important.
作为一般规则,我总是尝试尽可能远离 eval()。
然而,这个案例看起来是一个很好的候选者。
你说“不可能注入不安全的代码”,所以最大的问题是:数据库中是否有可能存在不工作的代码?
如果没有, eval() 是解决方案,但如果有适当的解析和错误日志记录等可能是更安全的选择。 (我相信使用 call_user_func_array() 理论上速度更快,因此任何解析开销可能都可以忽略不计)
As a general rule, i always try to stay as far away from eval() as possible.
This case, however, looks like a good candidate for it.
You say "There's no chance of unsafe code being injected", so the big question is: is there a chance of unworking code being in the database?
If not, eval() is the solution, but if there is then proper parsing and error logging/etc might be a safer bet. (i believe using call_user_func_array() is faster in theory, so any parsing overhead might become negligible)
我认为解析会增加开销,但唯一可以确定的方法是运行测试。 使用不同的函数尝试两种方法,看看结果如何。 使用代表您希望存储的内容的代码。
祝你好运!
I would think that parsing would add overhead, but the only way you can be sure is to run tests it. Try it both ways with various functions and see what your results are. Use code that represents what you expect to store.
Good luck!
使用 eval()。 其他任何事情都不值得付出努力——它们不会有任何积极的副作用。
Use eval(). Anything else is not worth the effort - they wouldn't have any positive side effects.
您可能想看看 runkit 扩展,它可以在沙箱中执行 php,而不影响正在运行的代码。
如果该代码应该影响您正在运行的代码,请使用 eval()。
You might want to take a look at the runkit extention, which can execute php in a sandbox not effecting the running code.
If the code is suppose to effect your running code, go for eval().
您也应该将要运行的代码包装在 try/catch 块中,以防出现错误(即使您说不会,但有可能,这是最佳实践)
You should wrap the code you're about to run in a try/catch block too, in case there is an error (even though you said there won't be, there is a possibility, and it is best practice)