PHP-将字符串替换为类似字符串的变量

PHP-将字符串替换为类似字符串的变量,php,variables,string,Php,Variables,String,所以字符串是这样的: "bla bla bla {VARIABLE} bla bla" 当我在函数中的某个地方使用这个字符串时,我想用$VARIABLE替换{VARIABLE}(或者用{}字符包装的任何其他大写字符串)$变量(和任何其他变量)将在该函数中定义 我可以这样做吗?使用正则表达式查找所有替换,然后迭代结果并替换它们。确保只允许您想要公开的变量 $TEST = 'one'; $THING = 'two'; $str = "this is {TEST} a {THING} to test

所以字符串是这样的:

"bla bla bla {VARIABLE} bla bla"
当我在函数中的某个地方使用这个字符串时,我想用$VARIABLE替换{VARIABLE}(或者用{}字符包装的任何其他大写字符串)$变量(和任何其他变量)将在该函数中定义


我可以这样做吗?

使用正则表达式查找所有替换,然后迭代结果并替换它们。确保只允许您想要公开的变量

$TEST = 'one';
$THING = 'two';
$str = "this is {TEST} a {THING} to test";

$result = preg_replace('/\{([A-Z]+)\}/e', "$$1", $str);
// white list of variables
$allowed_variables = array("test", "variable", "not_POST", "not_GET",); 

preg_match("#(\{([A-Z]+?)\}#", $text, $matches);

// not sure the result is in [1], do a var_dump
while($matches[1] as $variable) { 
    $variable = strtolower($variable);

    // only allow white listed variables
    if(!in_array($variable, $allowed_variables)) continue; 

    $text = str_replace("{".$match."}", $$match, $text);
}
这会有用的

$FOO = 'Salt';
$BAR = 'Peppa';
$string = '{FOO} and {BAR}';
echo preg_replace( '/\{([A-Z]+)\}/e', "$$1", $string );

但这似乎是一个糟糕的想法。

以下是另一个解决方案,但我同意其他人的看法,他们怀疑这是否是一件明智的事情

<?php

$string = "bla bla bla {VARIABLE} bla bla";
$VARIABLE = "foo";

function var_repl($matches)
{
  return $GLOBALS[$matches[1]];
}

echo preg_replace_callback("/{(\w+)}/", "var_repl", $string);

我很高兴找到了比尔·克里斯威尔的解决方案,但是
是否也可以替换这些变量:

字符串tmp=“{myClass.myVar}”

其中PHP代码类似于:

class myClass
{
    public static $myVar = "some value";
}

在其他一些答案的基础上(特别是比尔·卡温和布克的答案)

例如:
echo CurlyVariables::Replace(array('this' => 'joe', 'that' => 'home'), '{This} goes {that}', true);

使用
$$vars
$GLOBALS
都代表安全风险。用户应该能够明确定义可接受的标记列表

下面是我能想出的最简单的单功能通用解决方案。我选择使用双大括号作为标记分隔符,但您可以很容易地修改它

/**
 * replace_tags replaces tags in the source string with data from the vars map.
 * The tags are identified by being wrapped in '{{' and '}}' i.e. '{{tag}}'.
 * If a tag value is not present in the tags map, it is replaced with an empty
 * string
 * @param string $string A string containing 1 or more tags wrapped in '{{}}'
 * @param array $tags A map of key-value pairs used to replace tags
 * @param force_lower if true, converts matching tags in string via strtolower()
 *        before checking the tags map.
 * @return string The resulting string with all tags replaced.
 */
function replace_tags($string, $tags, $force_lower = false)
{
    return preg_replace_callback('/\\{\\{([^{}]+)\}\\}/',
            function($matches) use ($force_lower, $tags)
            {
                $key = $force_lower ? strtolower($matches[1]) : $matches[1];
                return array_key_exists($key, $tags) 
                    ? $tags[$key] 
                    : '';
            }
            , $string);
}
[编辑]添加了
force_lower
param


[编辑]添加了
force_lower
var to
use
list-感谢启动被拒绝编辑的人。

是的,但这看起来像是一个非常糟糕的模板引擎。我不会称之为模板引擎。这只是站点的一小部分,但我希望任何其他模块/插件都能够在字符串显示在屏幕上之前更改字符串。尝试{GLOBALS}并且您已经准备好被黑客攻击。如果您的解决方案成功,则/e修饰符被视为存在安全风险。它还公开了全局变量。我假设输入是可信的——也就是说,源字符串来自原始程序员,而不是站点访问者动态提供的。如果是这样,风险就会降低。如果它在一个函数中运行,那么它不会暴露任何全局变量。谢谢。是的,字符串不是真正动态的。但它可以由其他模块(脚本)更改。不管怎样,这些模块都可能有恶意代码,所以保护字符串不受它们攻击并不重要…@bouke:你不能只使用字母字符来做任何恶意的事情。所以它应该足够安全。@nikic,像$dbuser或$dbpass这样的变量呢?他们将被处置。另一方面,如果代码位于函数中,由于函数的作用域,这不会有问题。
$data_bas = 'I am a {tag} {tag} {club} {anothertag} fan.'; // Tests

$vars = array(
  '{club}'       => 'Barcelona',
  '{tag}'        => 'sometext',
  '{anothertag}' => 'someothertext'
);

echo strtr($data_bas, $vars);
$data_bas = 'I am a {tag} {tag} {club} {anothertag} fan.'; // Tests

$vars = array(
  '{club}'       => 'Barcelona',
  '{tag}'        => 'sometext',
  '{anothertag}' => 'someothertext'
);

echo strtr($data_bas, $vars);