如何执行存储在MySQL数据库中的PHP代码?

34
我想编写一个调用存储在MySQL数据库中的PHP页面的网页。存储在MySQL数据库中的页面包含我想在页面加载时运行的PHP和HTML代码。
我该如何实现这个功能?

11
谢谢您的提问。与下面许多“回答”相反,这是一个很好并且有用的问题。有很多合法的使用情况需要将PHP命令存储在数据库中。如果不知道具体情况就说“不要这样做”,那就显得有些自大了。 - Rid Iculous
7个回答

33
您可以使用eval命令来实现此功能。然而,由于使用此方法存在许多缺陷,我建议您不要这样做。调试更加困难,并且存在安全风险(DB中的坏内容会被执行)。例如,请参见这里。搜索“Eval is Evil”,您会发现很多例子说明为什么应该寻找其他解决方案。

另外,这篇博客文章是另一篇引用利用漏洞的好文章。它提到了过去vBulletin和phpMyAdmin漏洞的发生,这些漏洞是由于不当使用Eval造成的。


“Eval is evil” 的摘录:“允许任何用户提供的数据进入 eval() 调用是在寻求被黑客攻击。” - 好的,如果我使用存储在数据库中的自己的代码,并用于动态和快速的自定义表单生成呢? - Jeffz
@Jeffz 你最好非常确定没有坏代码进入那里。另外,为什么不把它放在几个代码文件中,而是放在数据库中呢? - Erik van Brakel
两种方法都可以,只要你知道自己在做什么。[A] 基于文件的方式更安全(特别是对于新手来说),[B] 数据库方式更加灵活,如果需要在代码上进行一些即时更改,更新数据库比更新、调整文件内容更容易。 - Jeffz

26

简单:

$x // your variable with the data from the DB
<?php echo eval("?>".$x."<?") ?>

请告诉我,这在许多应用程序中都非常好用。我不禁注意到每个人都很快地说它有多糟糕,但却缓慢地给出一个直截了当的答案...


1
我修复了你的Markdown - 如果你不将代码缩进四个空格,<?php ?> 将被视为HTML标签并隐藏起来。 - dbr
1
+1 这个解决方案实际上是有效的。仅仅应用 eval($x) 并不能解决问题,因为它会在 "<" 符号处破坏代码。所以这个答案解决了这个问题。向 Gapp 祝贺! - Devner

5

eval()函数在其他回答中已经涵盖了。我同意您应该限制使用eval,除非绝对需要。而不是在数据库中放置PHP代码,您可以只有一个类名,它具有称为execute()的方法。每当您需要运行自定义PHP代码时,只需实例化从数据库中获取的名称的类并在其上运行->execute()。这是一个更干净的解决方案,并且为您提供了极大的灵活性和显着提高了网站安全性。


3
你可以查看 PHP 中的 eval 函数。它允许你运行任意 PHP 代码。然而,它可能会带来巨大的安全风险,最好避免使用。

1

你有没有考虑使用源代码控制系统来存储不同分支,以适应各种安装(和其中不同的模块)?这是我能想到的几个应用程序配置最佳实践之一。你的需求并不罕见,所以这是一个过去已经被其他人解决的问题;而将代码存储在数据库中则是我认为你很难找到参考或被建议作为最佳实践的做法。

很高兴你发表了澄清。你可能无意中提出了一个需要合适问题的答案。


0
从数据库中读取PHP代码,并将其保存到具有唯一名称的文件中,然后包含该文件,这是运行PHP代码和调试它的简单方法。
$uniqid="tmp/".date("d-m-Y h-i-s").'_'.$Title."_".uniqid().".php";    
$file = fopen($uniqid,"w");
fwrite($file,"<?php \r\n ".$R['Body']);
fclose($file);                          
// eval($R['Body']);
include $uniqid;

0
我是通过在数据库中设置一个字段来标识需要执行的代码块中的某些唯一内容来实现这一点的。该单词出现在该代码文件的文件名中。我将字符串组合在一起,指向要包含的php文件。例如:
$lookFor = $row['page'];

include("resources/" . $lookFor . "Codebase.php");

通过这种方式,即使黑客能够访问您的数据库,他也无法直接放入恶意代码以执行。他可能会更改引用词,但除非他能够直接将文件放到服务器上,否则这对他没有任何好处。如果他能够直接将文件放到服务器上,那么如果他真的想要捣乱,您就完了。这只是我的个人看法。

是的,有理由执行存储的代码,但也有缺点。


1
你的说法是错误的,即使黑客能够访问你的数据库,这种包含方法仍然是安全的。它仍然容易受到几种攻击的影响,包括一种称为“null byte poisoning”或“null byte injection”的攻击,可以有效地删除(忽略)字符串的结尾。请参见此处此处获取更多详细信息。 - Justin Warkentin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接