// имена которых содержатся в ключах массива $Vars, а значения — в
// соответствующих значениях массива. Если $Vars===false, то вместо
// него используется массив $GLOBALS (то есть делаются доступными все
// глобальные переменные). Значение параметра $ReadFile "истина"
// указывает, что в $templ хранится не содержимое шаблона, а имя файла,
// из которого его можно получить.
// Замечание: параметр $Vars передается по ссылке, т. к. для
// массивов передача ссылки работает значительно быстрее, чем
// копирование.
function _RunTemplate($tmpl, $ReadFile, &$Vars)
{ // Перехватываем стандартный поток вывода
ob_start();
// Если $Vars опущен, использовать вместо него $GLOBALS. Мы
// используем ссылки для убыстрения работы, чтобы PHP не пришлось
// копировать значения, чем экономим время.
if($Vars===false) $Vars=&$GLOBALS;
// Делаем доступными коду шаблона все переменные. Также создаем
// ссылки из соображений производительности.
foreach($Vars as $k=>$v) $$k=&$Vars[$k];
// Включаем файл по include, либо же запускаем eval().
if($ReadFile) { include $tmpl; }
else eval("?>$tmpl;<?");
// Получаем содержимое буфера и закрываем его
$MTResult=ob_get_contents();
ob_end_clean();
// Возвращаем развернутый шаблон
return $MTResult;
}
// Функция "разворачивает" шаблон, тело которого расположено
// в файле $fname. Перед запуском переменные из $Vars делаются
// доступными шаблону (если этот параметр не опущен).
function ExpandFile($fname,$Vars=false)
{ return _RunTemplate($fname,true,$Vars);
}
// Функция "разворачивает" тело шаблона, явно заданное в $tmpl.
// Рекомендуется везде, где можно, применять ExpandFile() вместо
// данной функции, потому что это упрощает отладку.
function ExpandTemplate($tmpl,$Vars=false)
{ return _RunTemplate($tmpl,false,$Vars);
}
?>
Зачем нам две различных функции для "раскрытия" шаблона — ExpandTemplate() и ExpandFile()? Почему бы не использовать всегда ExpandTemplate(), предварительно загружая тело шаблона с помощью функций чтения файлов? Все дело в тонкостях обработки ошибочных ситуаций в PHP. А именно, в случае ошибки внутри файла, загружаемого по include, PHP сообщит нам имя этого файла. Если же ошибка произойдет в eval(), выведется только номер строки, что сильно затруднит отладку. Поэтому рекомендуется везде, где это допустимо, вызывать функцию ExpandFile().