Для тех, кто думает об оптимизации, такой тип рекурсии нельзя назвать оптимальным. Каждая тема делает свой вызов функции showMessages, который приводит к запросу к базе данных. Однако есть метод, при котором достаточно одного запроса к базе данных с последующим просмотром дерева сообщений из памяти, и автор оставляет его читателю для самостоятельных упражнений.
После щелчка на названии темы страница перезагружается с заданным значением messageID, и сценарий переключается в режим отображения сообщений. Поля сообщений отображаются в таблице. Если сообщение содержит какой-либо HTML-код, оно будет отображаться браузером, так как не было предпринято никаких попыток отфильтровать его. Это ограничение лучше всего использовать в качестве кода, добавляющего новое сообщение.
Независимо от двух режимов, отображается сообщение для добавления нового сообщения. Если сообщение добавляется, пока отображается список сообщений, то оно будет добавлено на корневом уровне. Если сообщение добавляется в то время, когда пользователь просматривает сообщение, оно будет считаться ответом. Новое сообщение будет порожденным по отношению к просматриваемому сообщению.
Это пример достаточно простой BBS. Более сложное решение может включать пре­доставление права добавления сообщения только аутентифицированным пользователям или сохранять сообщения закрытыми до того, как модератор не решит обратного. Этой же программной структурой можно воспользоваться для написания любого приложения, которое бы обрабатывало данные, введенные пользователями, как, например, это делается в гостевой книге. Достаточно хорошую реализацию BBS можно найти в проекте форума Брайана Муна (Brian Moon) (<http://www.phorum.org/>). 
23.4. Уровни абстракции базы данных
Представим создание Web-приложения, которое сначала использует в своей работе СУБД MySQL, а затем переводится на работу с СУБД Oracle. Все функции PHP являются различными, поэтому потребуется полная переделка всего. Кроме того, и MySQL, и Oracle используют немного различные диалекты языка SQL, поэтому вероятно потребуется внести изменения практически во все запросы. Одним из решений этой задачи является применение уровня абстракции. Он позволяет отделить логику работы вашего приложения от программного кода, с помощью которого реализован интерфейс с базой данных. Одна функция вызывает правильную функцию на основании типа базы данных, к которой делается запрос.
Вероятно, наиболее популярным уровнем абстракции является часть PEAR (<http://pear.php.net/>). Эта библиотека также содержит код, предназначенный для управления сеансами.
Несмотря на имеющиеся уровни абстракции, несовместимость между базами данных продолжают затруднять работу. Так, СУБД MySQL в своей работе использует специальную спецификацию в определениях столбцов, которая называется AUTO_INCREMENT. Это приводит к тому, что столбец должен заполняться автоматически целыми числами в возрастающем порядке. В СУБД Oracle таких же результатов можно добиться за счет применения последовательности и триггеров. Это различие с трудом поддается автоматизации. В 1999 году Скот Эмблер (Scott Ambler) в своей статье "Разработка устойчивого живучего уровня для реляционных баз данных" ("The Design of a Robust Persistence Layer for Relational Databases") (<http://www. ambysoft.com/persistenceLayer.html>) предложил решение. В этой работе была сделана попытка точного анализа проблемы и разработан детальный проект.
Для обеспечения устойчивости реализации уровня абстракции потребуется потребление дополнительных ресурсов. Некоторые из уникальных высокопроизводительных характеристик конкретных баз данных будут утеряны, таким образом, уровень абстракции обеспечивает обычные возможности. Но за этот счет приобретается независимость от конкретной базы данных.