Codeigniter3视图提交模板到控制器,渲染MySQL数据生成XML问题
解决CodeIgniter3中自定义XML模板变量未替换问题
问题原因
当前代码仅将用户提交的模板字符串直接拼接至XML中,PHP不会自动解析字符串内的$row['id']变量——因为它是用户输入的静态文本,而非PHP代码的一部分,因此会原样输出。
解决方案
推荐两种安全可靠的实现方式,优先使用第二种(更安全、语法更友好):
方式1:正则匹配替换(适配现有模板格式)
针对用户提交的'.$row['字段名'].'格式变量,通过正则匹配提取字段名,再替换为数据库对应值,同时转义XML特殊字符避免格式错误:
public function generate_google_post2() { if ($_POST) { $template = $this->input->post('add-list'); $products = $this->sitemap_model->get_all_products(); $xml = '<channel>'; foreach ($products as $row) { // 匹配 '.$row['xxx'].' 格式的变量并替换 $itemXml = preg_replace_callback( '/\.\$row\[\'(.*?)\'\]\./', function ($matches) use ($row) { $field = $matches[1]; // 转义XML特殊字符,避免生成无效XML return isset($row[$field]) ? htmlspecialchars($row[$field], ENT_XML1) : ''; }, $template ); $xml .= $itemXml; } $xml .= '</channel>'; header('Content-type: text/xml'); header('Content-Disposition: attachment; filename="file.xml"'); echo $xml; } }
方式2:使用CodeIgniter解析器(推荐,更安全友好)
利用CI内置的Parser类,让用户使用更简洁的模板语法(如{id}),避免直接处理PHP变量格式,同时杜绝代码注入风险:
控制器代码:
public function generate_google_post2() { if ($_POST) { $template = $this->input->post('add-list'); $products = $this->sitemap_model->get_all_products(); $xml = '<channel>'; // 加载CI解析器库 $this->load->library('parser'); foreach ($products as $row) { // 解析模板,将数组键与模板变量对应 $itemXml = $this->parser->parse_string($template, $row, TRUE); $xml .= $itemXml; } $xml .= '</channel>'; header('Content-type: text/xml'); header('Content-Disposition: attachment; filename="file.xml"'); echo $xml; } }
用户模板修改为:
<item> <gid>{id}</gid> </item>
注意事项
- 绝对避免使用
eval()函数解析用户模板:用户可提交恶意PHP代码,导致服务器安全风险。 - 必须对数据库字段值进行XML转义(如
htmlspecialchars(..., ENT_XML1)),防止生成格式无效的XML文件。
内容的提问来源于stack exchange,提问作者Marcin Wierzycki
相关产品推荐
相关产品推荐

