eval中的PHP eval无法读取预先定义的变量
在我解释这个问题之前,我知道使用eval的风险,但是在我的系统是如何构建的问题上,没有真正的其他方法可以做到这一点,而且它也仅适用于个人项目。(这是一个定制的cms,当我发布它时,它为我制作了物理文件,我只是通过db制作的,所以我不需要在远程工作时上传文件,这很简单) 让我们来解释我的问题,我有一个主php文件,它处理所有页面,所有页面都用代码和all存储在db中,并通过eval执行。 该系统还有一个include_db函数,基本上与数据库中的include from php normaly相同 但是,当我访问在第一个eval(主页)中定义的变量时,它不能从数据库中的包含eval中读取。 奇怪的是,函数可以通过第二次求值读出 有没有办法从主页的eval中生成的包含eval中正常访问变量? (我认为这是必须的,因为这些变量不是全局的,并且在函数中执行,但我不知道如何使每个变量都是全局的:() 提前谢谢 主页面上正在求值的代码:eval中的PHP eval无法读取预先定义的变量,php,function,eval,Php,Function,Eval,在我解释这个问题之前,我知道使用eval的风险,但是在我的系统是如何构建的问题上,没有真正的其他方法可以做到这一点,而且它也仅适用于个人项目。(这是一个定制的cms,当我发布它时,它为我制作了物理文件,我只是通过db制作的,所以我不需要在远程工作时上传文件,这很简单) 让我们来解释我的问题,我有一个主php文件,它处理所有页面,所有页面都用代码和all存储在db中,并通过eval执行。 该系统还有一个include_db函数,基本上与数据库中的include from php normaly相同
$skill = isset($_REQUEST['skill']) && is_string($_REQUEST['skill']) && isValidSkill($_REQUEST['skill']) ? $_REQUEST['skill'] : 'overall';
if(!isset($_REQUEST['player']))
include_db('highscore_overview');
else
include_db('highscore_player');
在include of overview中,我转储get_defined_vars(),它不返回我在include之前设置的$skill,只包含在main index.php(数据库等)中声明的变量首先免责声明:您永远不应该从数据库执行代码。这是一个很大的安全风险。这意味着每当有人成功访问您的数据库时(例如使用sql注入)现在还可以通过更改数据库中的代码在php中执行任意代码。您真的不应该这样做!
如果您使用数据库中的代码来实现自定义(电子邮件)模板,请考虑使用模板引擎来实现这一点。模板引擎的大多数语法是以无法破解的方式构建的,并且可以用原始PHP代码执行任意代码。
这就是说,我现在尝试回答最初的问题(因为我无法阻止你做你无论如何都不应该做的事情)。就变量范围而言,eval的行为就像一个函数。如果你想让它里面定义的变量成为全局变量,你必须手动使eval里面定义的每个变量都成为全局变量 您可以通过在eval中执行的每个代码中附加一个代码段来实现这一点,该代码段接受每个本地(eval定义的)变量并将其写入全局范围您的问题似乎与eval
无关,而是与变量范围有关。您应该发布示例代码来说明问题。我添加了我使用的代码,以及一些其他信息PHP版本可能对eval问题有用,我知道,但我的系统在“发布”时可以从db中生成所有物理文件但是关于你的答案,get_defined_vars()不包括从eval本身定义的变量。仅从物理文件。你知道如何解决这个问题吗?(例如,它看不到在include_db函数上面定义的$skill)get_defined_vars()如果在eval中执行,则包含在eval中定义的变量。如果未在my include_db函数中执行,则不显示在第一个eval中定义的项。所以$skill在include_db函数中是不可见的,或者我做错了什么?get_defined_vars()必须在eval中执行。仅在include_db中执行它是不够的,它必须是eval执行的代码的一部分。$skill是否在include_db中可见并不重要,因为include_db本身并没有使它成为全局的,eval执行的代码是全局的。eval中执行的代码与另一个函数中执行的代码类似,调用者看不到它的变量(在本例中包括_db)。这就是为什么get_defined_vars将在eval中执行,而不是在eval旁边的include_db中执行非常重要的原因。谢谢,我稍微更改了它,以检索$GLOBALS中的每个值,并按原始键设置它们,但它现在可以工作:)