Home » Php » How replace variable in string with value in php?

How replace variable in string with value in php?

Posted by: admin November 30, 2017 Leave a comment

Questions:

I have string like this in database(actual string contains 100s of word and 10s of variable)

i am a {$club} fan

i echo this string like this

 $club = "Barcelona";
echo $data_base[0]['body'];

My output is i am a {$club} fan.
I want i am a Barcelona fan
How can i do this?

Answers:

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.

Questions:
Answers:
if (preg_match_all('#$([a-zA-Z0-9]+)#', $q, $matches, PREG_SET_ORDER));
{
    foreach ($matches as $m)
    {
        eval('$q = str_replace(\''.$m[0].'\',$'.$m[1].',$q);');
    }
}

This matches all $variables and replaces them with the value.
i didn’t include the {}’s but shouldn’t be too hard to add them something like this…

if (preg_match_all('#\{$([a-zA-Z0-9]+)\}#', $q, $matches, PREG_SET_ORDER));
{
    foreach ($matches as $m)
    {
        eval('$q = str_replace(\''.$m[0].'\',$'.$m[1].',$q);');
    }
}

Though it seems a bit slower than hard coding each variable. And it introduces a security hole with eval. That is why my regular expression is so limited. To limit the scope of what eval can grab.

I wrote my own regular expression tester with ajax so i could see as i type if my expression is going to work. I have variables i like to use in my expressions so that i don’t need to retype the same bit for each expression.

Questions:
Answers:

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

Questions:
Answers:
/**
 * A function to fill the template with variables, returns filled template.
 * 
 * @param string $template A template with variables placeholders {$varaible}.
 * @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.' ');

}  

Questions:
Answers:

What you are looking for is nested string interpolation. A theory can be read at this post: http://thehighcastle.com/blog/21/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;

Questions:
Answers:

here is my solution:

$club = "Barcelona";

$string = 'i am a {$club} fan';

preg_match_all("/\{\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/",$string,$matches);

foreach ($matches[0] as $key => $var_name) {
    if (!isset($GLOBALS[$matches[1][$key]])) $GLOBALS[$matches[1][$key]] = 'default value';
    $string = str_replace($var_name, $GLOBALS[$matches[1][$key]], $string);
}

Questions:
Answers:

You can use a simple parser, that replaces {$key} with a value from a map if it exists.
use like $text = templateWith('hello $item}',array('item'=>'world'...));
My first version is:

/**
 * Template with a string and simple map.
 * @param string $template 
 * @param array $substitutions map of substitutions.
 * @return string with substitutions applied. 
 */
function templateWith(string $template, array $substitutions) {
    $state = 0; // forwarding
    $charIn = preg_split('//u', $template, -1, PREG_SPLIT_NO_EMPTY);
    $charOut = array();
    $count = count($charIn);
    $key = array();
    $i = 0;
    while ($i < $count) {
        $char = $charIn[$i];
        switch ($char) {
            case '{': 
                    if ($state === 0) {
                        $state = 1;
                    }
                break;
            case '}':
                if ($state === 2) {
                    $ks = join('', $key);
                   if (array_key_exists($ks, $substitutions)) {
                        $charOut[] = $substitutions[$ks];
                   }
                   $key = array();
                   $state = 0;
                }
                break;
            case '$': if ($state === 1) {
                        $state = 2;
                      }
                  break;
             case '\':    if ($state === 0) {
                           $i++;
                           $charOut[] = $charIn[$i];
                       }
                 continue;
             default:
                 switch ($state) {
                    default:
                    case 0: $charOut[] = $char;
                        break;
                     case 2: $key[] = $char;
                        break;
                   }
         } 
    $i++;
    }

    return join('', $charOut);
 }

Questions:
Answers:

Try preg_replace php function.

http://php.net/manual/en/function.preg-replace.php

<?php
    $club = "barcelona";
    echo $string = preg_replace('#\{.*?\}#si', $club, 'i am a {$club} fan');
?>

Questions:
Answers:

Something like this should solve your problem:

$club = "Barcelona";
$var = 'I am a {$club} fan';

$res = preg_replace('/\{$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/e', "$$1", $var);
echo "$res\n";

It’s a one-line preg_replace.

Update: with php 5.5 /e modifier is deprecated. You can use callback instead:

$club = "Barcelona";
$var = 'I am a {$club} fan';

$res = preg_replace_callback('/\{$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/',
                             create_function(
                                 '$matches',
                                 'extract($GLOBALS, EXTR_REFS | EXTR_SKIP); return $$matches[1];'),
                              $var);
echo "$res\n";

Note that this uses a hack of importing all global variables. This may not be exactly what you want. Possibly using closures would be a better idea.

Questions:
Answers:

you can use preg_replace_callback for get variable name like

$data_base[0]['body'] = preg_replace_callback(
    '#{(.*?)}#', 
    function($m) {
        $m[1]=trim($m[1],'$');
        return $this->$m[1];
    },
    ' '.$data_base[0]['body'].' '
);

Attention this code I wrote is for class($this); you can declare variable in to the class. then use this code for detect variable and replace them like

<?php 
class a{
  function __construct($array){
    foreach($array as $key=>$val){
     $this->$key=$val;
    }

  }
  function replace($str){
   return preg_replace_callback('#{(.*?)}#',function($m){$m[1]=trim($m[1],'$');return $this->$m[1];},' '.$str.' ');
  }   


}

$obj=new a(array('club'=>3523));

echo $obj->replace('i am a {$club} fan');

output:

i am a 3523 fan