数据库存储编码PHP代码替换:单PHP文件实现方案咨询
无需生成临时PHP文件的模板替换方案
背景与需求
数据库中存储着Base64编码的模板片段,解码后包含[PHP]标签。现有逻辑是提取标签内代码生成独立phpview文件,再用该文件内容替换原标签内代码。现要求不生成临时文件,仅通过单个PHP文件完成替换逻辑。
数据库存储的Base64编码内容
W1BIUF0KW1ZJRVdJRF0xWy9WSUVXSURdCjw/ICRjb25uID0gbmV3IFBETyggREJfRFNOLCBEQl9VU0VSTkFNRSwgREJfUEFTU1dPUkQgKTsgJHNxbCA9ICJzZWxlY3QgKiBmcm9tIHV6aXZhdGVsZSI7JHN0ID0gJGNvbm4tPnByZXBhcmUoICRzcWwgKTskc3QtPmV4ZWN1dGUoKTskY29ubiA9IG51bGw7IGZvcmVhY2ggKCAkc3QgYXMgJHN0cmVzdWx0ICkgeyA/Pgo8PyBlY2hvICRzdHJlc3VsdFsiaWQiXTs/Pgo8PyB9ID8+ClsvUEhQXQoKCgoKCgoKCgoKCgoKCgo=
解码后的模板内容
[PHP] [VIEWID]1[/VIEWID] <? $conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD ); $sql = "select * from uzivatele";$st = $conn->prepare( $sql );$st->execute();$conn = null; foreach ( $st as $stresult ) { ?> <? echo $stresult["id"];?> <? } ?> [/PHP]
现有实现代码
<? if ( !defined( 'DB_DSN' ) ) {require( "./../../pripojeni.php" );} $conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD ); function get_string_between( $string, $start, $end ) { $string = ' ' . $string; $ini = strpos( $string, $start ); if ( $ini == 0 ) return ''; $ini += strlen( $start ); $len = strpos( $string, $end, $ini ) - $ini; return substr( $string, $ini, $len ); } function replace_between($str, $needle_start, $needle_end, $replacement) { $pos = strpos($str, $needle_start); $start = $pos === false ? 0 : $pos + strlen($needle_start); $pos = strpos($str, $needle_end, $start); $end = $pos === false ? strlen($str) : $pos; return substr_replace($str, $replacement, $start, $end - $start); } $aktivniverzeproaktivniobsah = $_GET[ "id" ]; $sqlaktivniobsah = "select tp.* from template tp left join sekce sk on sk.template=tp.id left join verze vz on vz.id=sk.kverzi where vz.id=$aktivniverzeproaktivniobsah order by sk.poradi ASC"; $staktivniobsah = $conn->prepare( $sqlaktivniobsah ); $staktivniobsah->execute(); $conn = null; $contentdecoded=""; foreach ( $staktivniobsah as $aktivniobsah ) { $idcko = $aktivniobsah[ 'id' ]; $contentdecoded .= base64_decode( $aktivniobsah[ "obsah" ] ); } if ( str_contains( $contentdecoded, '[PHP]' ) ) { $str = get_string_between( $contentdecoded, '[PHP]', '[/PHP]' ); $idview = get_string_between( $contentdecoded, '[VIEWID]', '[/VIEWID]' ); if ( !empty( $idview )and!empty( $str ) ) { $fp = fopen( 'wms/admin/views/view' . $idview . '.php', 'w' ); fwrite( $fp, $str ); fclose( $fp ); } $dokument=file_get_contents( 'wms/admin/views/view' . $idview . '.php' ); $contentdecoded=replace_between($contentdecoded, '[PHP]', '[/PHP]', $dokument ); } echo $contentdecoded; ?>
优化方案(无需生成临时文件)
核心思路是直接使用提取到的PHP代码字符串完成替换,跳过写入文件再读取的冗余IO操作。同时修复原代码中的SQL注入风险,提升安全性。
修改后的完整代码
<? if ( !defined( 'DB_DSN' ) ) {require( "./../../pripojeni.php" );} $conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD ); function get_string_between( $string, $start, $end ) { $string = ' ' . $string; $ini = strpos( $string, $start ); if ( $ini == 0 ) return ''; $ini += strlen( $start ); $len = strpos( $string, $end, $ini ) - $ini; return substr( $string, $ini, $len ); } function replace_between($str, $needle_start, $needle_end, $replacement) { $pos = strpos($str, $needle_start); $start = $pos === false ? 0 : $pos + strlen($needle_start); $pos = strpos($str, $needle_end, $start); $end = $pos === false ? strlen($str) : $pos; return substr_replace($str, $replacement, $start, $end - $start); } $aktivniverzeproaktivniobsah = $_GET[ "id" ]; // 使用参数绑定防止SQL注入 $sqlaktivniobsah = "select tp.* from template tp left join sekce sk on sk.template=tp.id left join verze vz on vz.id=sk.kverzi where vz.id=? order by sk.poradi ASC"; $staktivniobsah = $conn->prepare( $sqlaktivniobsah ); $staktivniobsah->execute([$aktivniverzeproaktivniobsah]); $conn = null; $contentdecoded=""; foreach ( $staktivniobsah as $aktivniobsah ) { $idcko = $aktivniobsah[ 'id' ]; $contentdecoded .= base64_decode( $aktivniobsah[ "obsah" ] ); } if ( str_contains( $contentdecoded, '[PHP]' ) ) { $str = get_string_between( $contentdecoded, '[PHP]', '[/PHP]' ); $idview = get_string_between( $contentdecoded, '[VIEWID]', '[/VIEWID]' ); // 直接用提取到的PHP代码替换标签内容,无需临时文件 if ( !empty( $idview ) && !empty( $str ) ) { $contentdecoded = replace_between($contentdecoded, '[PHP]', '[/PHP]', $str); } } echo $contentdecoded; ?>
关键修改点
- 移除冗余IO操作:删除写入临时PHP文件和读取文件的代码块,直接用提取到的
$str变量作为替换内容,减少磁盘操作开销 - 修复SQL注入风险:将原代码中直接拼接
$_GET["id"]的SQL语句改为参数绑定写法,避免恶意注入攻击 - 规范代码写法:将条件判断中的
and替换为&&,符合PHP通用编码规范
特殊场景兼容
如果后续逻辑需要保留VIEWID关联的PHP文件,可以保留文件写入逻辑,但替换时仍直接使用$str,避免重复读取:
if ( !empty( $idview ) && !empty( $str ) ) { // 保留文件写入(若需后续调用) file_put_contents('wms/admin/views/view' . $idview . '.php', $str); // 直接用$str完成替换 $contentdecoded = replace_between($contentdecoded, '[PHP]', '[/PHP]', $str); }
内容的提问来源于stack exchange,提问作者Tomáš Strejček
相关产品推荐
相关产品推荐

