
本文介绍一种轻量、可嵌套的 PHP 模板变量替换方案,通过递归扁平化多维数组(如 var3.var5 → var3_var5),再结合 preg_replace 批量替换 {{key}} 占位符,无需依赖 Laravel,适用于自定义模板引擎开发。
本文介绍一种轻量、可嵌套的 php 模板变量替换方案,通过递归扁平化多维数组(如 `var3.var5` → `var3_var5`),再结合 `preg_replace` 批量替换 `{{key}}` 占位符,无需依赖 laravel,适用于自定义模板引擎开发。
在构建简易模板引擎时,常需将形如 {{var}} 或 {{user.profile.name}} 的占位符,按数据上下文动态替换为实际值。原生 PHP 不提供类似 Blade 的点号路径解析能力,而直接对多维数组调用 preg_replace 会导致“Array to string conversion”错误——因为 array_map 中的 $data 值若为数组,无法直接作为替换字符串。
核心思路是预处理数据结构:将嵌套数组递归展开为扁平化的“下划线分隔键”一维数组,例如:
[
'var' => 'hello',
'var2' => 'world',
'var3' => [
'var5' => 'asdf',
'var6' => ['last' => 'world']
]
]
// ↓ 经 flat_array 处理后变为:
[
'var' => 'hello',
'var2' => 'world',
'var3_var5' => 'asdf',
'var3_var6_last' => 'world'
]
以下是完整、健壮的实现代码(含边界保护与递归终止):
<?php function flat_array(&$array) {
foreach ($array as $key => $val) {
if (is_array($val)) {
// 将子数组每个键映射为 "父键_子键" 形式
foreach ($val as $subKey => $subVal) {
$newKey = $key . '_' . $subKey;
$array[$newKey] = $subVal;
}
// 删除原始嵌套键,避免重复或冲突
unset($array[$key]);
// 递归处理新加入的键(可能仍含数组,如 var3_var6 是数组)
flat_array($array);
break; // 每次只处理一个嵌套层级,避免 foreach 迭代中修改数组引发问题
}
}
}
// 使用示例
$content = "hello {{var}} world {{var2}} of what {{var3_var5}}?";
$data = [
"var" => "hello",
"var2" => "world",
"var3" => [
"var4" => "what",
"var5" => "asdf",
"var6" => ["last" => "world", "another" => ["wo" => "asfasfd"]]
]
];
// 扁平化数据
flat_array($data);
// 构建正则替换规则:{{key}} → 对应值
$patterns = array_map(fn($k) => '/\{\{' . preg_quote($k, '/') . '\}\}/', array_keys($data));
$result = preg_replace($patterns, array_values($data), $content);
echo $result; // 输出:hello hello world world of what asdf?
?>
✅ 关键注意事项:
-
preg_quote($k, '/')防止键名中含正则特殊字符(如.、*)导致匹配失败; -
unset($array[$key])后立即break,避免foreach在修改数组结构时跳过元素或报错; - 该方案不支持动态点号语法(如
{{var3.var5}}原样输入),需约定模板中使用下划线风格({{var3_var5}})——若需保留点号,可在flat_array中生成var3.var5键,并调整正则为'/\{\{' . str_replace('.', '\.', $k) . '\}\}/'; - 对于超深层嵌套(如
a.b.c.d.e),递归深度可控,无栈溢出风险(因每次仅展开一层)。
此方法简洁、无外部依赖,可无缝集成进微框架或静态页面生成工具中,是 Blade 变量替换逻辑的轻量级 PHP 实现范本。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











