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 fan
Comment puis-je faire cela?
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.
/**
* 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.' ');
}
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.
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
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;
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);
}
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);
}