Подсветка синтаксиса кода PHP

Постановка задачи

Итак, мы имеем некий контент в базе данных, в котором есть листинги кода. Для лучшей читаемости, листинги кода необходимо подсветить перед тем, как выводить их в браузер. Необходимо учесть, что контент содержит как обычный текст, так и код, который необходимо подсветить. И еще одно условие: листингов кода в контенте может быть несколько.

Решение

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

Алгоритм работы программы может быть следующий:

  1. Читаем нашу исходную строку до тега, в котором по договоренности находится код, который необходимо подсветить, вырезаем эту часть строки, и сохраняем ее в переменную;
  2. Читаем строку дальше, сохраняем во вторую переменную  часть строки между нашими тегами - это то, что необходимо подсветить;
  3. Читаем еще дальше, сохраняем в третью переменную  часть строки от окончания кода и до конца исходной строки,  проверям, есть ли еще код в оставшейся строке, и если есть, то делаем рекурсивный вызов нашей функции.
  4. Если кода больше нет, то выводим все в браузер.

В качестве примера, возьмем тег "code" и поместим внутри него, например такой код:

$first_str = substr($str, 0, strpos($str, $open_tag));

А вот собственно и сама функция подсветки синтаксиса кода:

function coloring_code($str) {
  //Переменная, в которую будем записывать контент
  $content = '';
  //Открывающий тег, внутри которого будет подсвечиваемый код
  $open_tag = 'Ваш тег';
  //закрывающий тег, внутри которого будет подсвечиваемый код
  $close_tag = 'Ваш тег';
  //Если в строке есть тег $open_tag
  if(strstr($str, $open_tag)) {
    //Вырезаем часть строки до тега $open_tag
    $first_str = substr($str, 0, strpos($str, $open_tag));
    //Вырезаем часть строки после тега $close_tag
    $post_str = substr(strstr($str, $close_tag), 7);
    //Записываем в переменную $content часть строки до тега $open_tag;  
    $content .= $first_str;
    //Находим начало участка подсветки кода (внутри тега $open_tag)
    $str = substr(strstr($str, $open_tag), 6);
    //Находим окончание участка подсветки кода (внутри тега $open_tag)
    $str = substr($str, 0, strpos($str, $close_tag));
    //Если нет тегов PHP, то проставляем их
    if(!strpos($str,'< ?') and substr($str,0,2)!='< ?') {
      $str='< ?'.trim($str).'? >';
    }
    //Убираем пробелы
    $str = trim($str);
    //Подсвечиваем код внутри тега $open_tag и добавляем его в переменную $content
    $content .= highlight_string($str, true);
    //Рекурсивный вызов функции
    //если внутри вырезанной части контента $post_str есть тег $open_tag
    if(strstr($post_str, $open_tag)) {
      $content .= coloring_code($post_str);
    //Если внутри вырезанной части контента $post_str нет тега $open_tag
    //выводим часть строки $post_str
    } else {
      $content .= $post_str;
    }
    //Возвращаем готовый контент
    return $content;
  } else {
    //Возвращаем исходный контент если не найден тег $open_tag
    return $str;
  }
}

Присвоим переменной "$str" в качестве значения нашу строку и вызовем функцию подсветки синтаксиса:

$str = '$first_str = substr($str, 0, strpos($str, $open_tag));';
echo coloring_code($str);

В результате получим:

$first_str = substr($str, 0, strpos($str, $open_tag));

В коде есть подробные комментарии, поэтому особых вопросов возникнуть не должно.