How can I replace a variable in a string with the value in PHP?

/**
 * A function to fill the template with variables, returns filled template.
 *
 * @param string $template A template with variables placeholders {$variable}.
 * @param array $variables A key => value store of variable names and values.
 *
 * @return string
 */

public function replaceVariablesInTemplate($template, array $variables){

 return preg_replace_callback('#{(.*?)}#',
       function($match) use ($variables){
            $match[1] = trim($match[1], '$');
            return $variables[$match[1]];
       },
       ' ' . $template . ' ');
}

Edit: This answer still gets upvotes, so people need to be aware that there's a security vulnerability in the naive interpolation technique present in the below code snippets. An adversary could include arbitrary variables in the input string which would reveal information about the server or other data in the runtime variable register. This is due to the way the general expression search is performed in that it finds any arbitrary variable name pattern, and then uses those variable names verbatim in the subsequent compact call. This causes clients to control server-side behavior similar to eval. I'm leaving this answer for posterity.


You are looking for nested string interpolation. A theory can be read in the blog post Wanted: PHP core function for dynamically performing double-quoted string variable interpolation.

The major problem is that you don't really know all of the variables available, or there may be too many to list.

Consider the following tested code snippet. I stole the regex from Mohammad Mohsenipur.

$testA = '123';
$testB = '456';
$testC = '789';
$t = '{$testA} adsf {$testB}adf 32{$testC} fddd{$testA}';

echo 'before: ' . $t . "\n";

preg_match_all('~\{\$(.*?)\}~si', $t, $matches);
if ( isset($matches[1])) {
    $r = compact($matches[1]);
    foreach ( $r as $var => $value ) {
        $t = str_replace('{$' . $var . '}', $value, $t);
    }
}

echo 'after: ' . $t . "\n";

Your code may be:

$club = 'Barcelona';
$tmp = $data_base[0]['body'];
preg_match_all('~\{\$(.*?)\}~si', $tmp, $matches);
if ( isset($matches[1])) {
    $r = compact($matches[1]);
    foreach ( $r as $var => $value ) {
        $tmp = str_replace('{$' . $var . '}', $value, $tmp);
    }
}
echo $tmp;

I would suggest the sprintf() function.

Instead of storing I am a {$club} fan, use I am a %s fan, so your echo command would go like:

$club = "Barcelona";

echo sprintf($data_base[0]['body'],$club);

Output: I am a Barcelona fan

That would give you the freedom of use that same code with any other variable (and you don't even have to remember the variable name).

So this code is also valid with the same string:

$food = "French fries";

echo sprintf($data_base[0]['body'], $food);

Output: I am a French fries fan

$language = "PHP";

echo sprintf($data_base[0]['body'], $language);

Output: I am a PHP fan


Use strtr. It will translate parts of a string.

$club = "Barcelona";
echo strtr($data_base[0]['body'], array('{$club}' => $club));

For multiple values (demo):

$data_base[0]['body'] = 'I am a {$club} fan.'; // Tests

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

echo strtr($data_base[0]['body'], $vars);

Program Output:

I am a Barcelona fan.

Tags:

Php

String