PHP: как убрать комментарии из html разметки

Владимир | | HTML, PHP, Web разработка, WordPress, Yii.

remove html comments

Прежде всего, несколько пояснений. Допустим, у вас есть html страница с комментариями, которые вы не хотите показывать посетителям сайта. Как их убрать? Естественно, это можно сделать с помощью любого текстового редактора 🙂 Но это не самый лучший вариант 😉

HTML комментарии помогают читать разметку во время разработки, особенно если макет страницы разбит на несколько частей. Т.е. открывающий тег может находиться в одном файле, а закрывающий – в другом. В таких случаях комментарий около закрывающего тега может действительно сэкономить ваше время.

С другой стороны, наличие таких комментариев в разметке хоть и немного, но увеличивает размер страницы, да показывать их посетителям как-то неправильно.

Общая идея

Для того, чтобы каким-то образом изменить страницу нам нужно получить доступ к её содержимому. В PHP для этого предусмотрены функции управления выводом. Они позволяют перехватить данные, которые скрипт отправляет браузеру и каким-то образом их изменить.

На практике это означает, что перед началом вывода нам нужно вызвать функцию ob_start, и в её первом параметре указать имя функции, которая будет обрабатывать данные. А в конце скрипта нужно вызвать функцию ob_end_flush, которая отправит данные браузеру.

Сам функция удаления комментариев из HTML разметки может выглядеть как-то так:

function removeHtmlComments($html) {
    return preg_replace('/<!--(.*?)-->/', '', $html);
}

Как видите, в ней с помощью регулярного выражения мы заменяем HTML комментарии на пустую строку.

Идея, надеюсь, ясна. Переходим к примерам.

«Чистый» PHP

<?php
ob_start('removeHtmlComments');

include 'header.php';
include 'content.php';
include 'footer.php';

ob_end_flush();
?>

Код, конечно, будет зависеть от структуры вашего приложения, но общий принцип не меняется – создаёте буфер перед формированием страницы и затем очищаете.

Yii фреймворк

Здесь задачу можно решить несколькими способами. Я приведу один из самых простых. Добавьте в массив в файле конфигурации (main.php) два элемента:

return array(
…
	'onBeginRequest' => function($event){
		return ob_start(function($html) {
			return preg_replace('/<!--(.*?)-->/', '', $html);
		});
	},
	'onEndRequest' => function($event){
		return ob_get_flush();
	}	
…
);

Здесь используются встроенные события фреймворка – onBeginRequest и onEndRequest. Первое событие происходит в начале обработки запроса, второе – перед её завершением.

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

С большинством других фреймворков ситуация аналогичная. Детали реализации, конечно, будут отличаться, но если вы знаете в какой последовательности происходит обработка запроса, то сможете легко определить, где именно нужно вызвать ob_start и ob_get_flush.

CMS (WordPress)

Многие системы управления контентом, также как и фреймворки, предоставляют возможность выполнить нужный код на разных этапах обработки запроса. Правда есть свои нюансы.

Рассмотрим в качестве примера WordPress. В большинстве случаев для решения нашей задачи будет достаточно в файл functions.php темы добавить такой код.

function removeHtmlComments($html) {
    return preg_replace('/<!--(.*?)-->/', '', $html);
}

function bufferStart() {
	ob_start('removeHtmlComments');
}

function bufferEnd() {
	ob_end_flush();
}

add_action('get_header', 'bufferStart');
add_action('wp_footer', 'bufferEnd');

Здесь используются два события get_header и wp_footer. Такой код будет работать, но проблема в том, что оба события вызываются из файлов темы, которая может иметь произвольную структуру. Проще говоря, тема может не вызвать эти события.

В таких случаях можно использовать собственные события. Для этого нужно найти открывающий и закрывающий теги <html>.

Перед открывающим добавляем

do_action('my_theme_output_begin');

после закрывающего –

do_action('my_theme_output_end');

Теперь у нас есть два события, которые можно использовать для создания и очистки буфера.

Если есть вопросы или замечания, пишите!

Успехов!

  • При использование этой ф-ции на данном сайте поломается счетчик.

    • Давно нужно было этот счетчик снести 🙂

  • Проблема возникнет и с <!—noindex—>.

    Можно немного изменить строку подлежащую замене, т.е. добавить, например еще один знак «-«, т.е. так <!— —>. И зная этот трюк комментарии подлежащие удалению оформлять именно так. Или наоборот, те, что нужно оставить маркировать предложенным мной способом.

    • А может стоит доработать функцию чтобы она научилась определять js/css/тэги разметки для ie/прочие ситуации?

      • Вполне. Однако, прелесть данного примера в его краткости, наворачивать селекцию дорого выйдет в итоге.

      • Действительно, перед использованием на продакшне функцию нужно доработать и всё тщательно протестировать, т.к. ситуации могут быть разные.

        И с удалением условных комментариев для ie тоже нужно быть аккуратным. Сейчас очень часто используется Varnish (особенно на облачных хостингах), который кэширует всю страницу целиком. Его, конечно, можно настроить так, чтобы кэш создавался для каждого браузера отдельно, но это другая история 😉

  • Дмитрий Куткин

    В Yii можно сделать проще:

    т.е. использовать 3 знака «-«. Фреймворк сам такие комменты подчистит при выводе.

    • Дмитрий Куткин

      Парсер дискуса «съел» пример комментария

  • Неплохо, неплохо. Не нужно так много коментировать, или если это далеете то нужно делать так, чтобы оно не мешало.
    http://progfromdelphi.com/