Наверняка у многих из нас есть свои наработки по BBcode`ам. Фичи и ноу-хау, методики тестирования безопасности и т.д. Может быть поделимся наработками?! Сделаем небольшой сборничек регулярок и теории по BBcod`ам, а то меня нубы запарили, на str_replace`е BBcode`ы делают, а потом спрашивают почему дизайн весь кривой стал... :lol: Ладно, раз уж затеял тему, вот: PHP: <?php //$msg - текст сообщения в котором есть PHP-код, выделенный тегами [ php ][/ php ]. // про htmlspecialchars беспокоится не стоит, возвращённая подмаска декодируется. $msg = preg_replace_callback("#\[php\](.*?)\[/php\]#si", create_function('$matches', ' $matches[1] = str_replace(">", ">", $matches[1]); $matches[1] = str_replace("<", "<", $matches[1]); $matches[1] = str_replace(""", "\"", $matches[1]); $matches[1] = str_replace("&", "&", $matches[1]); $matches[1] = highlight_string($matches[1], 1); $result = "<div class=\"bbcode_php\">".$matches[1]."</div>"; return $result;'), $msg); Всем тут знакомый BBcode подсветки синтаксиса PHP. Сам знаю, что странно реализовал, но работает вполне корректно. А вот и CSS к нему: [css]div.bbcode_php{ background-color:#FFFFFF; border-width:1px; border-color:#999999; border-style:dashed; margin:5px; padding:5px; }[/css]
PHP: <?php $text = htmlspecialchars($text); $text = preg_replace( '/\[php\](.*)\[\/php\]/Usie', "highlight_string(stripslashes(htmlspecialchars_decode('$1')), true)", $text); ?>
Sergey89 В php4 работать не будет. И как ты хочешь у себя html использовать для выделения?! Внешнюю функцию писать, очень удобно наверное Вот мой модернизированный вариант: PHP: <?php /********* Подсветка синтаксиса [ php][/ php] *********/ $msg = preg_replace_callback("#\[php\](.*?)\[/php\]#si", create_function('$matches', ' $matches[1] = str_replace(">", ">", $matches[1]); $matches[1] = str_replace("<", "<", $matches[1]); $matches[1] = str_replace(""", "\"", $matches[1]); $matches[1] = str_replace("&", "&", $matches[1]); $matches[1] = (stripos($matches[1], "<?php") != (int)1)? "<?php ".$matches[1]."" : $matches[1]; $matches[1] = highlight_string($matches[1], 1); $result = "<div class=\"bbcode_php\">".$matches[1]."</div>"; return $result;'), $msg); /********* Подсветка синтаксиса [ php][/ php] *********/ теперь автоматом вставляется префикс в виде <?php в случае необходимости
Давно забыл про него :wink: Не понял тебя... Mod: PHP: <?php $text = htmlspecialchars($text); $text = preg_replace( '/\[php\](.*)\[\/php\]/Usie', "highlight_string(stripslashes(htmlspecialchars_decode( (stripos('$1', '<?php') === false ? '<?php $1?>' : '$1') )), true)", $text); ?>
Sergey89, <php>а тута пхп код</php> Psih, ага, при этом многие перед сохранением в базу переводят ббкоды в хтмл
Sergey89 dark-demon У нас написано HTML -> BBcode. При этом этот парсер в BBCode переводит только строго то, что можно: Вплоть до определённых CSS атрибутов и их значений - всё остальное вырезаеться strip_tags() и после чего сохраняеться в базу. А всё потому, что юзеры пишут в визивике, поэтому обрабатываем HTML и оставляем только то, что мы разрешаем и вырезаем всё остальное. И вполне пашет. Кстати этот парсер можно найти здесь на форуме - он выложен в топике "Авторам движков на PHP". Он же в последствии переводит BBCode в валидный HTML при выводе (и для редактирования в визивике)
Psih, а не легче сразу перевести в валидный HTML? Зачем нужна двойная работа? Если можно сразу Или я чего-то не допонял?
Хранить в базе [e10] намного лучше чем <img src="/images/smiles/smile.gif" alt="" title="" /> . К тому же у нас есть ещё и WAP версия сайта - там HTML не катит, надо выводить WML Вопросы?
А ещё бывают RSS отсылка сообщений по мылу, экспорт в PDF, CSV, и.т.д. Всё что ввёл пользователь надо хранить так как оно пришло (я бы вообще в blob пихал, но это уже и в правду маразм)
Всё, нормально работает и выглядит красиво: PHP: <?php /********* Подсветка синтаксиса [ php][ /php] *********/ $msg = preg_replace_callback("#\[php\](.*?)\[/php\]#si", create_function('$matches', ' $matches[1] = str_replace(">", ">", $matches[1]); $matches[1] = str_replace("<", "<", $matches[1]); $matches[1] = str_replace(""", "\"", $matches[1]); $matches[1] = str_replace("&", "&", $matches[1]); $matches[1] = (stripos($matches[1], "<?php") === false)? "<?php ".$matches[1]."" : $matches[1]; $matches[1] = highlight_string($matches[1], 1); $result = "<div class=\"bbcode_php\"><b><u>PHP</u></b><br /><br />".$matches[1]."</div>"; return $result;'), $msg); /********* Подсветка синтаксиса [ php][ /php] *********/
Моё круче (завтра будет ровно 3 года как я это писал) PHP: <?php $text = substr($_POST["text"],0); $text = htmlspecialchars(stripslashes($text)); $text = strtr($text,"[[i]b[/i]]", "<b>"); $text = strtr($text,"[/[i]b[/i]]", "</b>"); $text = strtr($text,"[[i]i[/i]]", "<i>"); $text = strtr($text,"[/[i]i[/i]]", "</i>"); $text = strtr($text,"[[i]u[/i]]", "<u>"); $text = strtr($text,"[/[i]u[/i]]", "</u>"); $text = nl2br($text); ?> А теперь внимание вопрос, о чём я думал, и какую траву курил ?
Vladson PHP: <?php /********* Тип шрифта *********/ $patterns[] = "#\[b\](.*?)\[/b\]#si"; $replacements[] = "<b>\${1}</b>"; $patterns[] = "#\[u\](.*?)\[/u\]#si"; $replacements[] = "<u>\${1}</u>"; $patterns[] = "#\[i\](.*?)\[/i\]#si"; $replacements[] = "<i>\${1}</i>"; $msg = preg_replace($patterns, $replacements, $msg); unset($patterns); unset($replacements); /********* Тип шрифта *********/
Кстати юзать Код (Text): (.*?) надо окуратнее (многие его пихают куда не поподя а потом XSS на сайте плодятся как кролики)
Vladson Согласен. В моём случае с типом шрифта уязвимости нет, потому-что перед этим я делаю htmlspecialchars. А если мы хотим выделить ссылку, то там да, регулярку надо очень хорошо продумывать.
Код (Text): Хранить в базе [e10] намного лучше чем <img src="/images/smiles/smile.gif" alt="Very Happy" title="Very Happy" /> . 1. текстовые смайлики рулят ^_^ 2. не надо пихать в alt текст из title 3. title для смайликов не имеет смысла, потому как пользователи вставляют смайлики ориентируясь на изображение. соответственно предустановленная семантика для смайликов редко когда является адэкватной. яркий пример - стандартный в пхпББ смайлик показывающий язык. 4. <emo>^_^</emo> - такой вариант легко преобразовать во всё, что угодно, плюс можно выводить без преобразования - будет отображён обычный текстовый смайлик.
вообще говоря, конструкция Код (Text): <?php echo "[/php]"; ?> самодостаточна и ни в каких ббкодах не нуждается ;-) кстати, именно так и сделано на php.net...
Vitas, кстати, да. имхо, наиболее правильным было бы выделение исходников в отдельную сущность - что-то типа pastebin, но с интеграцией в форум...