web-dev-qa-db-fra.com

Comment remplacer une variable dans une chaîne par une valeur dans php?

J'ai une chaîne comme celle-ci dans la base de données (la chaîne actuelle contient 100 s de Word et 10 s de variable)

i am a {$club} fan

je fais écho à cette chaîne comme ça

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

Ma sortie est i am a {$club} fan. Je veux i am a Barcelona fanComment puis-je faire cela?

35
E-ebola virus

Utilisez strtr Il traduira des parties d’une chaîne.

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

Pour plusieurs valeurs ( 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);

Sortie du programme:

I am a Barcelona fan.
61
Husman
/**
 * 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.' ');

}  
5
tiffin joe
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);');
    }
}

Cela correspond à toutes les variables $ et les remplace par la valeur . Je n’ai pas inclus les {}, mais cela ne devrait pas être trop difficile d’ajouter quelque chose comme ça ...

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);');
    }
}

Bien que cela semble un peu plus lent que de coder en dur chaque variable. Et cela introduit une faille de sécurité avec eval. C'est pourquoi mon expression régulière est si limitée. Pour limiter la portée de ce que eval peut saisir.

J'ai écrit mon propre testeur d'expressions régulières avec ajax afin que je puisse voir ce que je tape si mon expression va fonctionner. J'ai des variables que j'aime utiliser dans mes expressions, de sorte que je n'ai pas besoin de retaper le même bit pour chaque expression.

4
Robert Russell

Je suggérerais la fonction sprintf().

au lieu de stocker i am a {$club} fan, utilisez i am a %s fan, ainsi votre commande echo ressemblerait à ceci:

$club = "Barcelona";

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

SORTIE: je suis un fan de Barcelone

Cela vous donnerait la liberté d'utiliser le même code avec n'importe quelle autre variable (et vous n'avez même pas à vous rappeler le nom de la variable).

donc ce code est également valide avec la même chaîne:

$food = "French Fries";

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

SORTIE: je suis un fan de frites

$language = "PHP";

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

SORTIE: je suis un fan de PHP

4
Moises Gumbs

Ce que vous recherchez, c'est une interpolation de chaîne imbriquée. On peut lire une théorie à cet article: http://thehighcastle.com/blog/21/wanted-php-core-function-for-dynamically-performing-double-quoted-string-variable-interpolation

Le problème majeur est que vous ne connaissez pas vraiment toutes les variables disponibles, ou qu'il y en a peut-être trop à énumérer. 

Considérez l'extrait de code testé suivant. J'ai volé l'expression régulière de 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";

Votre code peut être:

$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;
2
zamnuts

voici ma 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);
}
0
Jader A. Wagner

Vous pouvez utiliser un analyseur simple, qui remplace {$ key} par une valeur d'une carte si elle existe. utiliser comme $text = templateWith('hello $item}',array('item'=>'world'...));Ma première version est:

/**
 * 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);
 }
0
homberghp