С недавних пор, читатели моего блога могут комментировать статьи используя bb коды. До этого на сайте была собственная система парсинга комментариев. Она часто работала не корректно и имела кучу дыр. несколько раз пользователи блога демонстрировали мне, как легко на сайте можно разместить вредоносный JavaScript, осуществляя инъекцию. Поразмыслив, решил, что для моего проекта отлично подойдут bb коды. Для этого нашел библиотеку на сайте phpclasses, который github был наверно одним из основных источников готовых решений.
Класс с говорящим названием BBCode. Скачать его можно с моего сайта.
Если вы используете автозагрузку классов, то класс уже будет доступен для работы и ничего делать больше не надо. В противном случае файл нужно подключить
include "class.bbcode.php";
У класса есть всего один статичный публичный метод
BBcode::parse()
На вход подается текст с bb кодами, на выходе получаем валидный html. К примеру так
echo BBcode::parse('[b]Привет мир!!![/b]'); // <b>Привет мир!!!</b>
На этом заметку можно было бы завершить. Но этот сайт не про то, как «подключили готовый скрипт и радуемся». В форме комментариев ниже, вы можете заметить, что помимо стандартных bb кодов, перечисленных в википедии, доступны еще два кода: php и js. Так уж получается, что блог по большей части посвящен этим двум языкам. Их поддерживает система подсветки.
Такие коды, класс априори не поддерживает. Но мы программисты, и руки растут откуда надо. Поэтому добавим их поддержку сами.
Класс работает (неожиданно) на регулярных выражениях. Есть массив $simple_search, который содержит регулярные выражения, описывающие простые bb коды(b, i,u...) .
Никаких ухищренных защит в коде кстати нет. Простор для хакеров. Вам поможет узнать ip адрес сайта этот ресурс. И запустить для него парсер.
Здесь же находим строку
'/\[code\](.*?)\[\/code\]/is',
в соседнем массиве $simple_replace этот код имеет соответствие для замены
'<pre>$1</pre>',
Этого достаточно, чтобы включить поддержку своих кодов. Добавляем в конец $simple_search
'/\[php\](.*?)\[\/php\]/is', '/\[js\](.*?)\[\/js\]/is',
а в конец $simple_replace
'<pre class="brush:php;gutter:false;">$1</pre>', '<pre class="brush:jscript;gutter:false;">$1</pre>',
Готово. Подсветку кода на блоге делает Syntax Highlighter, соответственно в вашем случае замена может быть слегка иной, но принцип будет тем же.
Замечу, что скрипт никак не защищает содержимое ваши bb тегов от html. Это нужно сделать самому. Чтобы никто не смог ввести в комментарий html я сделал так
$content = bbcode::parse(htmlspecialchars($content));
И еще один глюк, связанный непосредственно с Syntax Highlighter. Он показывает <br> переносы строк. это я решил так. В класс добавляем замену.
// Parse bbcode $s = preg_replace(self::$simple_search, self::$simple_replace, $s); while(preg_match('/(<pre[^>]*>[^<]*)<br[\s\/]*>(.*<\/pre>)/Uuis',$s)) $s = preg_replace('/(<pre[^>]*>[^<]*)<br[\s\/]*>(.*<\/pre>)/Uuis',"$1$2",$s);
Желаю удачи вам и вашим проектам.
Комментарии
Но, это не всегда удобно. Любой добавленный специфический тег в набор - автоматически добавляет сложностей и необходимость ручной замены символов.