views:

69

answers:

4

Hi

so the string is like this:

"bla bla bla {VARIABLE} bla bla"

when I use this string somewhere in a function I want to replace {VARIABLE} with $variable (or any other uppercase strings with wrapped within {} charcters). $variable (and any other variables) will be defined inside that function

Can i do this?

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

$result = preg_replace('/\{([A-Z]+)\}/e', "$$1", $str);
Alex Howansky
As your solution does the trick, the /e modifier is regarded a security risk. It also exposes global variables.
bouke
I'm assuming that the input is trusted -- i.e., that the source string is coming from the original programmer and not provided dynamically from a site visitor. If that's the case, the risk is mitigated. And if it's running inside a function as stated, it won't expose any globals.
Alex Howansky
thanks. yes the string is not really dynamic. but it can be changed by other modules (scripts). these modules can have malicious code anyway, so it's not important to protect the string from them...
Alex
@bouke: You couldn't do anything malicious only using alphabetic characters. So it should be secure enough.
nikic
@nikic, what about variables like $dbuser or $dbpass? They would be disposed. On the other hand, if the code is located in a function this would be no problem because of the function's scope.
bouke
+8  A: 

Use a regular expression to find all substitutions, then iterate over the result and replace them. Be sure to only allow variables you would want to expose.

// 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);
}
bouke
+1 for whitelisting the variables!
Bill Karwin
+1  A: 

This will work....

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

but it just seems like an awful idea.

BIllium
+1  A: 

The following is another solution, but I agree with other folks who are dubious about whether this is a wise thing for you to do.

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