我有一个PHP脚本,在全局命名空间中设置了一些变量:
$domain = 'example.com';
$hostname = 'www.' . $domain;
我正在使用file_get_contents:将外部文件读取到脚本中的字符串变量中
$file_contents = file_get_contents('external_file.tpl');
外部文件(和字符串$file_contents
)包含与变量名相对应的占位符。
127.0.0.1 {{domain}} {{hostname}}
我希望将变量$file_contents
中的所有占位符替换为已经设置的各自的PHP变量。我希望它能通用地工作(不需要对占位符/变量名进行硬编码)。我不想编辑文件,只想编辑字符串的内容。
做这件事最简单的方法是什么?
- 分析文件中{{和}}之间的项
- 检查是否存在全局变量
- 搜索并替换
像这样:
$matches = array();
preg_match('/{{([a-zA-Z0-9_]+)}}/', $file_contents, $matches);
foreach ($matches as $match)
{
// You might want to check to make sure the variable is a string
if (isset($GLOBALS[$match]))
{
str_replace('{{'.$match.'}}', $GLOBALS[$match], $file_contents);
}
}
免责声明:我不认为允许在任何模板中使用任意变量是个好主意。
函数get_defined_vars()
以variable_name => value
的形式创建所有当前可用变量的数组(THIS包括SUPERGLOBALS LIKE$_SERVER AND$_GET!)
字符串转换函数strtr(string $str, array $replace_pairs)
可以将关联数组的键替换为它们在字符串中的值。
他们共同组成了一个强大但危险的联盟。以下代码将用$domain
的值替换domain
,依此类推:
echo strtr(file_get_contents('external_file.tpl'), get_defined_vars());
添加{{...}}
只需付出一点额外的努力:
$vars = get_defined_vars();
$replace = array();
foreach ($vars as $key => $value) {
$replace['{{' . $key . '}}'] = $value;
}
echo strtr(file_get_contents('external_file.tpl'), $replace);
负责任地使用它!记住不要相信任何用户输入。
您可以使用preg_replace_callback
来执行此操作,但您需要将替换项放入数组中。
例如
$domain = 'example.com';
$newString = preg_replace_callback(
'/{{([^}}]+)}}/',
function ($matches) {
foreach ($matches as $match) {
if (array_key_exists($match, $_GLOBALS))
return $replace[$match];
}
},
$file_contents
);
为该特定正则表达式返回的匹配项将是数组
array [
'{{hostname}}',
'hostname',
'{{domain}}',
'domain'
]
这就是为什么我们要用array_key_exists
进行检查
好吧,伙计们,我从其他答案中提取了一些零碎的东西,并提出了我认为对我来说最好的解决方案:
$domain = 'example.com';
$hostname = 'www.' . $domain;
$file_contents = '127.0.0.1 {{domain}} {{hostname}}';
$result = preg_replace_callback(
"/{{(.+?)}}/",
function ($matches) {
return $GLOBALS[$matches[1]];
},
$file_contents
);
这个答案结合了@TonyDeStefano、@dops和@fschmengler的观点。所以请投票给他们@BugaDániel也为他的评论提供了帮助。
您可以简单地使用str_replace
来完成此操作。既然你知道位置持有者会是什么样的人,就试试这样的东西:
str_replace(['{{domain}}','{{hostname}}'],[$domain, $hostname], $file_contents);
这将为全局变量做工作
<?php
$domain = 'example.com';
$hostname = 'www.' . $domain;
$file_contents = "127.0.0.1 {{domain}} {{hostname}}";
foreach($GLOBALS as $key => $value){
if(!is_string($value) && !is_numeric($value)){
continue;
}
$file_contents = str_replace('{{'.$key.'}}', $value, $file_contents);
}
var_dump($file_contents);
将输出:
string '127.0.0.1 example.com www.example.com' (length=37)