Получить содержимое файла используя регулярные выражения в PHP
01.11.2017 08:04:33 pm
Работая над одним php сценарием (парсер, шаблонизатор), делал замену кода в шаблонах используя регулярные выражения, вот так:
По моему данная конструкция отлично справляется со своей работай. Код, что я привел для примера находит в шаблоне
Далее измененный код сохраняем в файл кэша, и уже из кэша выводим на экран.
Все просто и понятно, но когда я дошел до подключения шаблона в шаблоне столкнулся с тем, что такой код вовсе не пролезет:
этот код не будет работать. То есть он будет работать, но подключать указанный шаблон он не будет.
Тут я подумал, что можно не подключать шаблон каждый раз (в кэше), а получить содержимое подключаемого шаблона и вставить это содержимое вместо
Но такой код не работал, а выдавал ошибку. Немного поэкспериментировав сделал так:
Этот код работает, так как мне надо! Я добился своего. Но вскоре на официальном сайте php я прочитал, что модификация
Верным решением было использовать функцию preg_replace_callback() вместо preg_replace(). Функцию preg_replace_callback() - ищет по регулярному выражению и изменяет используя функцию обратного вызова. Вот что получилось в итоге:
Этот код рабочий и не является устаревшим.
Если в подключенном шаблоне есть ещё одно подключение, оно выйдет на экран, как текст
заменить на:
Теперь все лишние подключения не попадут на экран пользователя.
Хотя лучше, конечно убирать лишнее из самого кода, а не пытаться спрятать...
$cache_tpl = preg_replace('/\{echo (.*?)}/', '<?php echo $1; ?>', $cache_tpl);
По моему данная конструкция отлично справляется со своей работай. Код, что я привел для примера находит в шаблоне
{echo $...}
и заменяет его на:
<?php echo $...; ?>
Далее измененный код сохраняем в файл кэша, и уже из кэша выводим на экран.
Все просто и понятно, но когда я дошел до подключения шаблона в шаблоне столкнулся с тем, что такой код вовсе не пролезет:
$cache_tpl = preg_replace('/\{include (.*?)}/', '<?php include $1; ?>', $cache_tpl);
этот код не будет работать. То есть он будет работать, но подключать указанный шаблон он не будет.
Тут я подумал, что можно не подключать шаблон каждый раз (в кэше), а получить содержимое подключаемого шаблона и вставить это содержимое вместо
{include ...}
и все! Код написал так:
$cache_tpl = preg_replace('/\{include (.*?)}/', file_get_contents($1), $cache_tpl);
Но такой код не работал, а выдавал ошибку. Немного поэкспериментировав сделал так:
$cache_tpl = preg_replace('/\{include (.*?)}/e', 'file_get_contents("$1")', $cache_tpl);
Этот код работает, так как мне надо! Я добился своего. Но вскоре на официальном сайте php я прочитал, что модификация
e
, которую я использую в своем выражении устарело и её использование небезопасно. Стал проводить эксперименты и искать альтернативу дальше.
Верным решением было использовать функцию preg_replace_callback() вместо preg_replace(). Функцию preg_replace_callback() - ищет по регулярному выражению и изменяет используя функцию обратного вызова. Вот что получилось в итоге:
# Обработка INCLUDE
$cache_tpl = preg_replace_callback('/\{include (.*?)}/',
function($include_tpl)
{
return file_get_contents($dir_tpl . $include_tpl[1] . $ext_tpl);
},
$cache_tpl);
Этот код рабочий и не является устаревшим.
Если в подключенном шаблоне есть ещё одно подключение, оно выйдет на экран, как текст
include
, а не как содержимое подключенного шаблона. Что бы не вышло лишнего на экран делаем так:
return file_get_contents($dir_tpl . $include_tpl[1] . $ext_tpl);
заменить на:
$include_tpl = file_get_contents($dir_tpl . $include_tpl[1] . $ext_tpl);
if (preg_match('/\{include (.*?)}/', $include_tpl))
{
return preg_replace('/\{include (.*?)}/', null, $include_tpl);
}
else
{
return $include_tpl;
}
Теперь все лишние подключения не попадут на экран пользователя.
Хотя лучше, конечно убирать лишнее из самого кода, а не пытаться спрятать...
- Жалоба