如何用PHP中的值replacestring中的variables?

我在数据库中有这样的string(实际string包含100个字和10个variables)

i am a {$club} fan 

我回声这样的string

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

我的输出是i am a {$club} fan 。 我想i am a Barcelona fan我该怎么做?

使用strtr它将翻译一个string的部分。

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

对于多个值( 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); 

节目输出:

 I am a Barcelona fan. 
 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);'); } } 

这匹配所有的$variables,并用它们replace它们。 我不包括{}的,但不应该太难以添加像这样的东西…

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

虽然看起来比硬编码每个variables慢一点。 它引入了一个eval的安全漏洞。 这就是为什么我的正则expression式如此有限。 限制eval可以抓取的范围。

我用ajax写了自己的正则expression式testing器,所以我可以看到,如果我的expression式正常工作。 我有我喜欢在我的expression式中使用的variables,以便我不需要为每个expression式重新键入相同的位。

我会build议sprintf()函数。

而不是存储i am a {$club} fan使用i am a %s fan ,所以你的回声命令会像这样:

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

输出:我是巴塞罗那球迷

这将给你自由使用相同的代码与任何其他variables(你甚至不必记住variables名称)。

所以这段代码对于同一个string也是有效的:

 $food = "French Fries"; echo sprintf($data_base[0]['body'],$food); 

输出:我是一个炸薯条的粉丝

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

输出:我是一个PHP粉丝

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

你正在寻找的是嵌套的string插值。 一个理论可以阅读在这个职位: http : //thehighcastle.com/blog/21/wanted-php-core-function-for-dynamically-performing-double-quoted-string-variable-interpolation

主要的问题是你并不知道所有可用的variables,或者可能有太多可以列出的variables。

考虑下面的testing代码片段。 我从mohammad mohsenipur偷了正则expression式。

 $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"; 

您的代码可能是:

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

这里是我的解决scheme:

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

你可以使用一个简单的parsing器,如果它存在的话,它将用一个来自映射的值replace{$ key}。 像使用$text = templateWith('hello $item}',array('item'=>'world'...)); 我的第一个版本是:

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

试试preg_replace php函数。

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

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

像这样的东西应该可以解决你的问题:

 $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"; 

这是一个单行的preg_replace

更新:与PHP 5.5 /e修饰符已弃用。 你可以使用callback代替:

 $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"; 

请注意,这使用导入所有全局variables的黑客。 这可能不是你想要的。 可能使用闭包将是一个更好的主意。

你可以使用preg_replace_callback来获取variables名称

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

注意我写的代码是为class($this); 你可以在类中声明variables。 然后使用这个代码检测variables,并将其replace

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

输出:

 i am a 3523 fan