从数据库读取PHP代码未解析执行及替代eval方案问询
问题根因
PHP 仅会解析执行当前被服务端PHP处理器加载的脚本文件内的原生<?php ?>标签,你从数据库查询得到的notification字段内容本质是普通字符串,直接输出时不会触发PHP的代码解析流程,只会被当作纯文本发送到前端,浏览器也不会识别服务端PHP标签,所以标签内容直接被忽略,最终出现, you are % popular today.的输出结果。
你之前使用eval时输出eval(), you are eval()% popular today.,是因为你错误地将<?php echo ?>标签也放入了待执行的字符串中,eval不需要包裹PHP标签,直接传入代码表达式即可。
解决方案
方案一:占位符模板替换(无需eval,安全稳定,推荐)
不要在数据库存储可执行代码,改为存储带占位符的通知模板,完全规避代码注入风险,同时满足动态修改通知内容的需求。
- 数据库
notification字段存储内容格式示例:
{username}, you are {popularity}% popular today.
- 修改
processes/notifications.php代码,增加占位符替换逻辑:
$stmt = $pdo->prepare("SELECT notification FROM notifications"); $stmt->execute(); $html = "<div class='notifications'>"; // 提前定义允许使用的变量/函数返回值映射表 $replaceMap = [ '{username}' => $user['name'][0], '{popularity}' => popularity() ]; while($f = $stmt->fetch()){ // 替换模板中的占位符为实际值 $renderedNotification = strtr($f['notification'], $replaceMap); $html .= '<a href="'.$link.'">'.$renderedNotification.'</a>'; } $html .= "</div>"; echo $html;
后续需要修改通知模板时,直接修改数据库中带占位符的文本即可,无需调整业务代码。
方案二:eval适配方案(仅推荐在必须存储动态逻辑的场景使用,注意安全风险)
如果必须要在数据库存储可变的PHP表达式,按照以下格式存储和调用即可避免语法报错:
- 数据库
notification字段存储内容(不要加多余引号、不要加PHP标签):
$user['name'][0] . ', you are ' . popularity() . '% popular today.'
- 调整
processes/notifications.php中的执行逻辑:
$stmt = $pdo->prepare("SELECT notification FROM notifications"); $stmt->execute(); $html = "<div class='notifications'>"; while($f = $stmt->fetch()){ // 拼接合法的eval执行语句 $evalCode = '$renderedNotification = ' . $f['notification'] . ';'; eval($evalCode); $html .= '<a href="'.$link.'">'.$renderedNotification.'</a>'; } $html .= "</div>"; echo $html;
⚠️ 风险提示:eval会执行传入的任意PHP代码,如果数据库内容被篡改,攻击者可以执行任意服务端操作,请确保你能完全控制数据库存储的内容,否则不要使用该方案。
内容的提问来源于stack exchange,提问作者Relaxing Music
相关产品推荐
相关产品推荐

