Лучший способ заменить переменные в текстовом формате с помощью PHP

Каков наилучший способ взять какой-то простой текст (а не код 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" 

Если это из надежного источника, вы можете использовать (драматическую паузу) 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 

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]; } 

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

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

Это должно быть $ домашнее животное? Может ли это быть <?= $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; в //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. 

В зависимости от ситуации 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, обратите внимание, что параметры поиска и замены могут принимать массивы значений для поиска и замены.

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

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