PHP - заменить строку переменной, названной как строка

поэтому строка выглядит так:

"bla bla bla {VARIABLE} bla bla"

когда я использую эту строку где-то в функции, которую я хочу заменить{} ПЕРЕМЕННОГО спеременные $ (или любые другие строки в верхнем регистре, заключенные в символы {}). переменная $ (и любые другие переменные) будет определена внутри этой функции

Я могу это сделать?

 Alex21 сент. 2010 г., 21:38
я бы не назвал это движком шаблонов. это только для небольшой части сайта, но я хочу, чтобы любые другие модули / плагины имели возможность изменять строку до ее отображения на экране.
 halfdan21 сент. 2010 г., 21:34
Да, но это выглядит как очень плохая идея механизма шаблонов.
 bcosca21 сент. 2010 г., 21:59
попробуйте {GLOBALS} и вы готовы к взлому

Ответы на вопрос(8)

$data_bas = 'I am a {tag} {tag} {club} {anothertag} fan.'; // Tests

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

echo strtr($data_bas, $vars);

что нашел решение Билла Крисвелла, но можно ли заменить такие переменные:

string tmp = "{myClass.myVar}";

Где код PHP будет что-то вроде:

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

чтобы найти все подстановки, затем переберите результат и замените их. Обязательно разрешите только те переменные, которые вы хотели бы предоставить.

// 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);
}
 Bill Karwin21 сент. 2010 г., 21:48
+1 за внесение в белый список переменных!

Это будет работать ....

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

но это просто кажется ужасной идеей.

е) ...

 class CurlyVariables {

  private static $_matchable = array();
  private static $_caseInsensitive = true;

  private static function var_match($matches)
  {
    $match = $matches[1];

    if (self::$_caseInsensitive) {
      $match = strtolower($match);
    }

    if (isset(self::$_matchable[$match]) && !is_array(self::$_matchable[$match])) {
      return self::$_matchable[$match];
    }

    return '';
  }

  public static function Replace($needles, $haystack, $caseInsensitive = true) {
    if (is_array($needles)) {
      self::$_matchable = $needles;
    }

    if ($caseInsensitive) {
      self::$_caseInsensitive = true;
      self::$_matchable = array_change_key_case(self::$_matchable);
    }
    else {
      self::$_caseInsensitive = false;
    }

    $out = preg_replace_callback("/{(\w+)}/", array(__CLASS__, 'var_match'), $haystack);

    self::$_matchable = array();

    return $out;
  }
}

Пример:

echo CurlyVariables::Replace(array('this' => 'joe', 'that' => 'home'), '{This} goes {that}', true);
Решение Вопроса
$TEST = 'one';
$THING = 'two';
$str = "this is {TEST} a {THING} to test";

$result = preg_replace('/\{([A-Z]+)\}/e', "$1", $str);
 vatavale02 авг. 2017 г., 21:13
Можно ли заменить {var ["key"]} на $ var ["key"]?
 Alex Howansky21 сент. 2010 г., 21:52
Я предполагаю, что входные данные являются доверенными, то есть, что исходная строка исходит от исходного программиста и не предоставляется динамически от посетителя сайта. Если это так, риск смягчается. И если он работает внутри функции, как указано, он не будет выставлять глобальные переменные.
 NikiC21 сент. 2010 г., 22:44
@bouke: Вы не могли сделать ничего вредоносного, только используя буквенные символы. Так что это должно быть достаточно безопасно.
 Alex21 сент. 2010 г., 21:59
Благодарю. да строка не очень динамическая. но это может быть изменено другими модулями (скриптами). в любом случае эти модули могут содержать вредоносный код, поэтому не важно защищать строку от них ...
 Bouke22 сент. 2010 г., 11:15
@nikic, а как насчет таких переменных, как $ dbuser или $ dbpass? Они будут расположены. С другой стороны, если код находится в функции, это не будет проблемой из-за области действия функции.
 Bouke21 сент. 2010 г., 21:44
Поскольку ваше решение работает, модификатор / e считается угрозой безопасности. Это также выставляет глобальные переменные.

$$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 пары

[править] Добавленоforce_lower вар вuse list - Спасибо тому, кто начал отклоненное редактирование.

но я согласен с другими людьми, которые сомневаются в том, что это мудрый шаг для вас.

<?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);

Ваш ответ на вопрос