2013-02-25 71 views
28

我在數據庫中的字符串是這樣的(實際的字符串包含字的100S和可變的10S)如何用PHP中的值替換字符串中的變量?

i am a {$club} fan 

我贊同這個字符串像這樣

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

我的輸出爲i am a {$club} fan。 我想要i am a Barcelona fan 我該怎麼做?

+0

[str_replace()函數(http://php.net/manual/en/function.str-replace.php) – Eggplant 2013-02-25 11:00:32

+0

我的字符串包含20變量這樣。需要我使用str_replace()fn 20次? – 2013-02-25 11:06:28

+0

preg_replace是你在找什麼。 – 2013-02-25 11:07:53

回答

46

使用strtr它會翻譯一部分字符串。

$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. 
+2

我的字符串包含20個像這樣的變量。需要我使用str_replace()fn 20次? – 2013-02-25 11:04:38

+0

這將是簡單的出路。您也可以使用關聯數組和循環的組合。看到我上面的代碼。 – Husman 2013-02-25 11:07:56

+0

@messifan使用此解決方案時,請務必記得每次將另一個變量添加到模板時更新您的聯想數組。 – 2013-02-25 11:27:41

-1

像這樣的東西應該解決您的問題:

$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修飾符已棄用。您可以使用回調代替:

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

請注意,這使用導入所有全局變量的黑客。這可能不是你想要的。可能使用閉包將是一個更好的主意。

+2

eval是一個非常糟糕的建議 – David 2013-02-25 11:14:05

+0

@David:我知道,這就是我爲什麼寫這是一件壞事。 – 2013-02-25 11:20:11

+0

如果這是一件不好的事情,甚至發佈它有什麼意義?或者,也許它應該是一個評論,而不是一個答案。 – 2013-02-25 11:29:12

-1

您可以使用preg_replace_callback得到變量名狀

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

注意該代碼我寫的是class($this);,你可以到類中聲明變量。然後使用此代碼檢測變量,代替它們像

<?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 
+0

剛剛在串上試過你的代碼_I是{club} fan_(沒有'$'符號) - 得到了以下結果:** PHP致命錯誤:當不在第3行的/tmp/p.php中的對象上下文中時使用$ this ** – 2013-02-25 11:25:19

+0

@AleksG我在回答這段代碼是爲了上課你不能在課堂上使用它 – 2013-02-25 11:26:57

+0

我已經破解了你的代碼,並且我遇到的問題是像$ club這樣定義的變量出來了回調函數的範圍,所以我最終得到'未定義的變量:$ club' – 2013-02-25 11:27:34

-1

嘗試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'); 
?> 
+0

但是這將取代所有的變數與$俱樂部 – 2013-02-25 11:17:47

+0

@JacobTomlinson是的,它會.. – 2013-02-25 11:18:28

+3

@Dipesh OP需要用它的相應值替換每個變量。你顯然誤解了這個問題。 – 2013-02-25 11:22:20

2

你在找什麼是嵌套的串插。一個理論可以在這篇文章中閱讀:http://thehighcastle.com/blog/21/wanted-php-core-function-for-dynamically-performing-double-quoted-string-variable-interpolation

主要問題是,你不知道所有可用的變量,或可能有太多的列表。

考慮下面的測試代碼片段。我從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"; 

您的代碼可能是:

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

這符合所有$變量並用值替換它們。 我不包括{}的,但不應該太難添加它們是這樣的......

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

雖然它似乎比硬慢一點編碼每個變量。它引入了一個eval的安全漏洞。這就是爲什麼我的正則表達式如此有限。限制eval可以抓取的範圍。

我用ajax編寫了自己的正則表達式測試程序,所以我可以看到,如果我的表達式要工作,就可以輸入。我有我喜歡在我的表達式中使用的變量,以便我不需要爲每個表達式重新輸入相同的位。

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

} 
+0

不使用全局變量的最佳解決方案。謝謝! – WillianLKeller 2016-05-19 02:21:34

0

這裏是我的解決方案:

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

我建議sprintf()功能。的

而不是存儲i am a {$club} fan使用i am a %s fan,所以你的echo命令會是這樣的:

$club = "Barcelona"; 

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

OUTPUT:我是巴薩球迷

這將使你使用的自由與任何相同的代碼其他變量(並且你甚至不必記住變量名)。

因此,這段代碼也適用於有相同的字符串:

$food = "French Fries"; 

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

OUTPUT:我是一個炸薯條風扇

$language = "PHP"; 

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

OUTPUT:我是一個PHP風扇

0

你可以使用一個簡單的解析器,如果它存在,它將使用映射中的值替換{$ 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); 
}