Лучший способ замены переменных в простом тексте с использованием PHP - PullRequest
8 голосов
/ 12 ноября 2008

Как лучше всего взять какой-нибудь простой текст (не код PHP), который содержит переменные в стиле PHP, а затем подставить в значение переменной. Это довольно сложно описать, так что вот пример.

// -- myFile.txt --
Mary had a little $pet.

// -- parser.php --
$pet = "lamb";
// open myFile.txt and transform it such that...
$newContents = "Mary had a little lamb.";

Я подумывал об использовании регулярных выражений или, возможно, eval(), хотя я не уверен, что будет проще. Этот сценарий будет работать только локально, поэтому любые опасения, связанные с проблемами безопасности и eval(), не применяются (я думаю?) .

Я также просто добавлю, что могу получить все необходимые переменные в массив, используя get_defined_vars():

$allVars = get_defined_vars();
echo $pet;             // "lamb"
echo $allVars['pet'];  // "lamb"

Ответы [ 6 ]

11 голосов
/ 12 ноября 2008

Regex будет достаточно просто. И это не заботится о вещах, которые eval() будут считать синтаксической ошибкой.

Вот шаблон для поиска имен переменных в стиле PHP.

\$\w+

Я бы, вероятно, воспользовался этим общим шаблоном и использовал бы массив PHP для поиска каждого найденного соответствия (используя (preg_replace_callback()). Таким образом, регулярное выражение нужно применять только один раз, что быстрее в долгосрочной перспективе .

$allVars = get_defined_vars();
$file = file_get_contents('myFile.txt');

// unsure if you have to use single or double backslashes here for PHP to understand
preg_replace_callback ('/\$(\w+)/', "find_replacements", $file);

// replace callback function
function find_replacements($match)
{
  global $allVars;
  if (array_key_exists($match[1], $allVars))
    return $allVars[$match[1]];
  else
    return $match[0];
}
5 голосов
/ 12 ноября 2008

Если это из надежного источника, который вы можете использовать (драматическая пауза) eval () (вздох ужаса из аудитории).

$text = 'this is a $test'; // single quotes to simulate getting it from a file
$test = 'banana';
$text = eval('return "' . addslashes($text) . '";');
echo $text; // this is a banana
2 голосов
/ 13 ноября 2008

Должно ли это быть $ pet? Может ли это быть <?= $pet ?> вместо этого? Потому что, если так, просто используйте include. В этом вся идея php как движка шаблонов.

//myFile.txt
Mary had a little <?= $pet ?>.

//parser.php

$pet = "lamb";
ob_start();
include("myFile.txt");
$contents = ob_end_clean();

echo $contents;

Это будет эхо:

Mary had a little lamb.
2 голосов
/ 12 ноября 2008

Вот что я только что придумал, но мне все равно было бы интересно узнать, есть ли лучший способ. Приветствия.

$allVars = get_defined_vars();
$file = file_get_contents('myFile.txt');

foreach ($allVars as $var => $val) {
    $file = preg_replace("@\\$" . $var . "([^a-zA-Z_0-9\x7f-\xff]|$)@", $val . "\\1", $file);
}
0 голосов
/ 13 ноября 2008

Вы можете использовать strtr :

$text = file_get_contents('/path/to/myFile.txt'); // "Mary had a little $pet."
$allVars = get_defined_vars(); // array('pet' => 'lamb');
$translate = array();

foreach ($allVars as $key => $value) {
    $translate['$' . $key] = $value; // prepend '$' to vars to match text
}

// translate is now array('$pet' => 'lamb');

$text = strtr($text, $translate);

echo $text; // "Mary had a little lamb."

Вы, вероятно, захотите выполнить предварительное добавление в get_defined_vars (), чтобы не повторять циклы дважды. Или, что еще лучше, просто убедитесь, что назначенные вами ключи изначально соответствуют идентификатору, который вы используете в myFile.txt.

0 голосов
/ 12 ноября 2008

В зависимости от ситуации, str_replace может добиться цели.

Пример:

// -- myFile.txt --
Mary had a little %pet%.

// -- parser.php --
$pet = "lamb";
$fileName = myFile.txt

$currentContents = file_get_contents($fileName);

$newContents = str_replace('%pet%', $pet, $currentContents);

// $newContents == 'Mary had a little lamb.'

Когда вы смотрите на str_replace, обратите внимание, что параметры поиска и замены могут принимать массивы значений для поиска и замены.

...