Как написать простейший шаблонизатор на регулярных выражениях для замены конструкций типа {{ var }} и {if (condition)} на валидный PHP-код?

Создание простейшего шаблонизатора на регулярных выражениях — отличный способ понять, как работают популярные движки вроде Blade или Twig. Рассмотрим реализацию шаг за шагом.

## Основная идея

Шаблонизатор принимает строку с шаблоном, находит специальные конструкции с помощью `preg_replace` или `preg_replace_callback` и заменяет их валидным PHP-кодом, который затем выполняется через `eval()` или сохраняется во временный файл и подключается через `include`.

## Шаг 1. Замена переменных {{ var }}

Конструкция `{{ var }}` должна превращаться в «.

php
function compileVariables(string $template): string {
return preg_replace(
‘/{{s*(w+)s*}}/’,
»,
$template
);
}

Регулярное выражение `{{s*(w+)s*}}` ищет двойные фигурные скобки с именем переменной внутри. `s*` допускает пробелы вокруг имени.

## Шаг 2. Замена условий {if (condition)}

Конструкция `{if (condition)}` превращается в «.

php
function compileIf(string $template): string {
$template = preg_replace(
‘/{ifs*((.+?))}/’,
»,
$template
);
$template = preg_replace(
‘/{/if}/’,
»,
$template
);
return $template;
}

## Шаг 3. Циклы {foreach ($arr as $item)}

php
function compileForEach(string $template): string {
$template = preg_replace(
‘/{foreachs*((.+?))}/’,
»,
$template
);
$template = preg_replace(
‘/{/foreach}/’,
»,
$template
);
return $template;
}

## Шаг 4. Компиляция и рендеринг

php
function render(string $templatePath, array $vars = []): string {
$template = file_get_contents($templatePath);
$template = compileVariables($template);
$template = compileIf($template);
$template = compileForEach($template);

$tmpFile = sys_get_temp_dir() . ‘/’ . md5($templatePath) . ‘.php’;
file_put_contents($tmpFile, $template);

extract($vars);
ob_start();
include $tmpFile;
return ob_get_clean();
}

## Шаг 5. Пример использования

Шаблон `hello.tpl`:

Привет, {{ name }}!

{if ($age >= 18)}

Вы совершеннолетний.

{/if}

Вызов:
php
echo render(‘hello.tpl’, [‘name’ => ‘Иван’, ‘age’ => 25]);

## Важные замечания

— **Безопасность**: всегда экранируйте вывод переменных через `htmlspecialchars`, чтобы избежать XSS.
— **Кэширование**: сохраняйте скомпилированные файлы и проверяйте дату изменения исходника, чтобы не компилировать шаблон при каждом запросе.
— **Вложенные конструкции**: простые регулярные выражения плохо справляются с глубокой вложенностью — для сложных случаев используйте рекурсивные паттерны или парсер.

Такой шаблонизатор подходит для учебных проектов и небольших утилит, когда подключение Twig или Blade избыточно.


Задайте вопрос нейросети

Не нашли ответ? Спросите ИИ — он подготовит развёрнутую статью.