Подтвердить что ты не робот

Как заменить переменную в строке со значением в php?

У меня есть строка, подобная этой в базе данных (фактическая строка содержит 100 слов и 10 переменных)

i am a {$club} fan

i повторяю эту строку следующим образом

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

Мой вывод i am a {$club} fan. Я хочу i am a Barcelona fan Как я могу это сделать?

4b9b3361

Ответ 1

Используйте strtr Он преобразует части строки.

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

Для нескольких значений (Демо):

$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

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

}  

Ответ 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

Ответ 4

То, что вы ищете, это вложенная строковая интерполяция. На этом посту можно прочитать теорию: 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;

Ответ 5

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, поэтому я мог видеть, как я набираю, если мое выражение будет работать. У меня есть переменные, которые мне нравятся в моих выражениях, поэтому мне не нужно повторно указывать один и тот же бит для каждого выражения.

Ответ 6

Я нашел эти подходы полезными время от времени:

$name = 'Groot';
$string = 'I am {$name}';
echo eval('return "'.$string.'";');
$data = array('name' => 'Groot');
$string = 'I am {$data[name]}';
echo eval('return "'.$string.'";');
$name = 'Groot';
$data = (object)get_defined_vars();
$string = 'I am {$data->name}';
echo eval('return "'.$string.'";');

Ответ 7

вот мое решение:

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

Ответ 8

Вы можете использовать простой синтаксический анализатор, который заменяет {$ 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);
 }

Ответ 9

вы можете использовать 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 

Ответ 11

Что-то вроде этого должно решить вашу проблему:

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

Обратите внимание, что это использует взлом импорта всех глобальных переменных. Это может быть не совсем то, что вы хотите. Возможно, использование замыканий было бы лучшей идеей.