б) В связи с тем, что многие файлы будут подключаемыми необходимо указать корректные пути к этим файлам.
в) для простоты установки модуль должен быть выполнен в виде папки с файлами, и устанавливаться простым копированием этой папки в корень сайта.
База данных:
Модуль должен автоматически подключаться к базе данных и далее работать с ней. При отсутствии базы данных он должен её создать, а также автоматически создать в этой базе таблицы необходимые для работы. Решаем с помощью запросов к MySQL.
Доступ:
а) Необходима авторизация пользователей. Регистрация пользователей должна исключать регистрацию ботов. Поэтому модуль должен содержать минимальную защиту от подобных регистраций. Решаем с помощью капчи и подтверждения регистрации по адресу электронной почты.
б) У администратора модуля должна быть возможность управления пользователями и комментариями. Решаем созданием административного раздела модуля.
4. Внешний вид:
а) Элементы модуля должны иметь свой стиль. Решаем в файле style.css модуля.
б) чтобы не сильно влиять на дизайн сайта элементы регистрации, авторизации и элементы непосредственного вывода комментариев необходимо разделить. Решаем созданием раздельных контроллеров для элементов авторизации и печати.
2.3 Реализация логики
Рис. 4 Блок схема модуля,
Учитывая вышеизложенное, изобразим полученные результаты графически. Результат представлен на рис.3. Модуль комментариев будет представлять из себя папку, содержащую блоки кода в виде файлов и вложенных папок, указанных на рисунке 3.
2.4 Подключения, корень сайта
Как видно файлов достаточно много даже при самом схематичном рассмотрении. возникает вопрос, а как же они будут друг с другом взаимодействовать? Совершенно очевидно, что придется делать ссылки и вставки частей кода друг в друга. Возникает следующий вопрос: если модуль планируется подключать неизвестно к чему, т.е. не известен сайт, неизвестен хостинг, неизвестны директории, то как с этим неизвестно, чем взаимодействовать? Ведь необходимо прописывать пути. Каким образом? Немного теории.
Любой сайт существует в двух измерениях[5]: реальном и виртуальном. Для всех посетителей это виртуальный веб-сервер. На котором нет файлов, а есть виртуальные адреса URI. Если вы видите строку в браузере http://site.ru/ufo/phantom.html это не файл. Это URI, виртуальный адрес. Никакого файла с именем phantom.html на сервере может вообще не быть. Вполне вероятно, что и папки ufo там тоже нет, а все URL адреса обрабатываются одним единственным PHP файлом. И браузер работает именно с виртуальными адресами. Браузер не может видеть реальную файловую структуру сервера. Он не видит никаких дисков C, D, E и т.д. он видит только URL адреса, а не файлы.
Для разработчиков, сайт это программа, выполняющаяся на совершенно конкретном реальном компьютере. С совершенно конкретным жестким диском, директориями и файлами. И скрипт, работая со своими данными, подгружая другие скрипты, работает именно с реальными файлами, на реальном физическом диске.
Еще раз: ПУть к файлу скрипта и виртуальный адрес этого скрипта для просмотра в браузере это не одно и то же
Как достучаться до файла? Вариантов два: абсолютный и относительный путь.
Если путь указывается от корня системы, то это путь абсолютный. Абсолютный путь в PHP это полный путь к папке или файлу. Вот пара примеров для разных операционных систем:
С:\OpenServer\domains\test.ru\index.php для Open Server на Windows
/var/www/html/test.ru/index.php для Ubuntu
Как видим, это полный путь от корня диска до конкретного файла или папки.
Виртуальный адрес этого скрипта при просмотре через браузер, будет:
http://www. test.ru\index.php
Для браузера это самый полный путь, который только может быть. Он начинается от корня сайта.
В юникс-системах и на веб сайтах корень обозначается косой чертой "/", в Windows начинается c буквы диска.
Относительный путь это путь без указания корня.
У относительных путей в PHP есть один недостаток они строятся по своей логике, которую не интересуют наши желания. В результате этого нужный файл зачастую просто не обнаруживается. Происходит это потому что когда мы подключаем скрипт по относительному пути, например include ufo.php, то сначала PHP попытается найти этот файл в папках, указанных в директиве include_path, затем будет искать файл в папке, в которой находится подключающий скрипт, и под конец попытается найти файл в папке текущего рабочего каталога.
Что это значит на практике. Допустим у нас есть в корне сайта две папки chat и ufo, и в папке ufo у нас есть скрипт phantom.html. Так вот, при помощи относительного пути вставить наш phantom.html в файлы папки chat не получится. От слова никак не получится. Почему? Попробую привести аналогию с движением автомобиля.
Рис. 5 относительный путь дорога в одну сторону,
где СТАРТ корень сайта.
Движение из точки старт возможно только в одном направлении. Или налево или направо. Мы не можем взять предметы в месте chat и затем отвезти их в место ufo. Если автомобиль выезжает из позиции старт в направлении ufo и по прибытии в ufo обнаружится, что нужные предметы для этого места отсутствуют, то все. Мы оказались у разбитого корыта. Вернуться назад за нужными предметами мы не можем. Движение одностороннее.
Рис. 6 Абсолютный путь двустороннее движение,
где СТАРТ корень сайта.
При абсолютном же пути движение двустороннее и мы всегда можем вернуться обратно на старт. Отправится в ufo. Узнать, что там необходимо. Сделать крюк допустим до места chat и вернуться обратно уже с полным пакетом всего что надо. Если и сейчас что-то забыли, не вопрос. Можно опять съездить куда надо и вернуться. Т.е. абсолютный путь дает спокойное и предсказуемое поведение в точках назначения.
Поэтому использовать полностью относительные пути в PHP я бы не советовал вообще. Целесообразнее определить с помощью PHP корневую директорию веб-сервера, а местоположения файлов указывать относительно ее.
Значит остается абсолютный путь. Применительно к решению данной задачи есть два варианта по созданию абсолютных путей:
Вариант А: использовать константу __DIR__.
__DIR__ константа для получения абсолютного пути к папке, это директория файла. Если используется внутри подключаемого файла, то возвращается директория этого файла. Это эквивалентно вызову dirname(__FILE__). Возвращаемое имя директории не оканчивается на слеш, за исключением корневой директории[6].
Применительно к нашей задаче данная константа не совсем удобна, зато будет работать везде. Неудобство будет заключаться в том, что в первую очередь нас интересует путь к корню сайта, а поскольку мы не знаем заранее его название, то придется использовать обходной способ. И этот способ будет работать только когда мы будем знать названия папок из которых будут вызываться include. Заключается способ в том, что на тех страницах, где будут вызываться include прописываются папки для поиска загружаемых файлов. Это делается при помощи функции set_include_path которая задает значение настройки конфигурации include_path на время выполнения скрипта.
Конфигурационная директива include_path указывает список директорий, в которых функции require, include, fopen(), file(), readfile() и file_get_contents() ищут файлы. Формат соответствует формату системной переменной окружения PATH: список директорий, разделенных двоеточием в Unix или точкой с запятой в Windows[7].
При поиске подключаемых файлов PHP отдельно рассматривает каждое значение в include_path. Он проверяет первый путь, если файл в нем не найден, то он переходит к следующему, и так до тех пор, пока не найдет подключаемый файл, либо вернет E_WARNING или E_ERROR.
Проще говоря, необходимо указать папку, в которой будут искаться подключаемые файлы.
Таким образом, чтобы подключить файлы, в начале страницы, где требуется включение, будет нужно прописать код:
Листинг А. Получение пути к корню сайта. Размещается вначале страницы.
$p = explode('ufo', __DIR__);
echo $p[0];
set_include_path(get_include_path() . PATH_SEPARATOR . $p[0]);
где ufo имя папки из которой вызывается файл. В примере указано ufo, но по факту любое.
Для сайта news и папки ufo в константе __DIR__ будет такой путь:
C:\OSPanel\domains\news\ufo
При помощи функции explode этот путь делится на две части. Разделителем будет служить название каталога, в данном примере ufo. В итоге в $p[0] будет содержаться левая часть:
C:\OSPanel\domains\news\
т.е. путь к корню сайта.
И теперь можно подключать файлы из любых каталогов следующим образом:
include "chat/нужный скрипт"; или include "ufo/нужный скрипт";. Мне кажется это довольно неудобно, хотя и будет работать везде. Поэтому рассмотрим вариант Б.
Вариант Б: использовать $_SERVER['DOCUMENT_ROOT'].
'DOCUMENT_ROOT' это директория корня документов, в которой выполняется текущий скрипт, в точности та, которая указана в конфигурационном файле сервера[mnl]. Значение этой переменной дает путь к корню сайта. И подключение файла будет выглядеть так:
include $_SERVER['DOCUMENT_ROOT']./нужный файл;
Как мне кажется, вариант Б более удобен, поэтому в дальнейшем все подключения будут делаться через $_SERVER['DOCUMENT_ROOT'].
3. Создание тестового сайта
Ну, что ж приступим. Для упрощения разработки модуля на этапе разработки, воспользуемся не готовым шаблоном, а создадим свой простейший сайт одностраничник. Для этого переходим в папку с установленным «Open Server». По умолчанию она находится по пути: C:\OSPanel. Далее переходим в папку «domains» и создаем там тестовый отладочный сайт. Для этого создадим в папке «domains» подпапку. Название выбирайте какое хотите. Название этой папки будет именем вашего сайта. Я назвал её news. Затем открываем редактор и создаем в нем текстовый документ со следующим кодом:
Листинг 2. index.html Путь: news/index.html
Значимость этих проблем настолько очевидна, что начало повседневной работы по формированию позиции способствует подготовке и реализации новых предложений!
Значимость этих проблем настолько очевидна, что повышение уровня гражданского сознания влечет за собой процесс внедрения и модернизации модели развития. Практический опыт показывает, что рамки и место обучения кадров способствует повышению актуальности соответствующих условий активизации.
Сохраняем файл в папке news как index.html. Теперь у нас есть стартовая страница тестового сайта. В тегах
содержится обычный текст заглушка. Стили к данной странице применять не будем.
Запускаем «Open Server». В разделе мои сайты должен появиться новый сайт news. Запускаем его. Если все сделано правильно, в браузере должен появиться сайт «news» и на нем текст заглушка.
Так как дальнейшая работа предполагает работу с PHP, создаем в редакторе в этой же папке «news» файл .htaccess со следующим содержимым
Листинг 3. .htaccess Путь: news/.htaccess
#Включаем обработку php в html файлах
AddType application/x-httpd-php .php .htm .html
#Устанавливаем кодировку по умолчанию
AddDefaultCharset utf-8
Сохраняем в корне сайта, т.е. в папке «news».
При сохранении в меню «Файл» выбрать «Сохранить как».
В выпадающем списке «Тип файла» выбрать «Все файлы».
Ввести в качестве имени .htaccess.
Нажать на кнопку «Сохранить».
Файл .htaccess (англ. hypertext access) используется для настройки веб-сервера на котором хранится сайт пользователя. А меняя настройку веб-сервера, мы влияем на работу сайта. В данном случае серверу дается команда обрабатывать PHP код в HTML документах и устанавливать по умолчанию кодировку «UTF-8»
Создаем папку модуля комментариев. Ее можно создать в любом месте, но разместить в корне сайта. Назовем папку «chat». В этой папке создадим две подпапки:
admin для файлов администрирования;
say для файлов управления комментариями.
В этой же папке chat создадим файл style.css для того чтобы настраивать внешний вид элементов модуля. Пока этот файл будет пустой. Должно получиться как на рис. 7, 8.
Рис. 7 Содержание тестового сайта news.
Рис. 8. Содержание папки chat сайта news.
Комментарии без смайлов, как-то не интересно. Поэтому добавим праздника. Смайлов. Для этого в папке «say» создаем подпапку «smiles» в которую загружаем набор смайлов. В этом модуле загружен набор «Колобки» в формате GIF. Вы можете загрузить любые другие смайлы. Папка «smiles» будет проверяться на наличие изображений при первом запуске модуля и в случае если в ней будут обнаружены изображения, то они автоматически будут обработаны в качестве смайлов.
Рис. 9. Содержимое папки smiles.
На рисунке 7 представлена структура тестового сайта на данном этапе.
Рис. 10. Содержание тестового сайта news.
Таким образом, у нас получился рабочий тестовый сайт с размещенным на нем модулем комментариев с набором смайлов.
База данных
Теперь необходимо определиться для чего нам нужна база данных (далее БД), с ее системой управления и с тем, что в ней будет храниться. Я выбрал систему управления БД MySQl. Во-первых потому что ранее уже приходилось с ней работать, во-вторых, это самая распространенная на сегодня БД и на нее есть огромное количество справочной информации. Итак: MySQl система управления реляционными, т.е. представленными в виде таблиц, базами данных (далее СУБД). Что в ней хранить?
В контексте задачи храниться будут:
Комментарии.
Ответы на комментарии.
Данные пользователей.
Данные о странице на которой размещаются комментарии.
Смайлы (без смайлов я комментарии не представляю).
При создании таблиц используем правило: каждый объект должен располагаться в отдельной таблице.
Объекты будут следующие: комментарии, ответы на комментарии, пользователи, права пользователей, смайлы. Еще одна таблица будет связывать права пользователя с данными в других таблицах.
Для хранения комментариев создаем таблицу «say». Таблица будет содержать следующую информацию о комментарии:
id уникальный номер комментария;
saytext текст комментария;
userid идентификатор пользователя;
page_id идентификатор страницы;
saydate дата добавления комментария;
Для ответов на комментарии создаем таблицу «reply». Таблица будет содержать следующую информацию.
id уникальный номер ответа на комментарий;
replytext текст комментария;
userid идентификатор пользователя;
replyid идентификатор комментария;
saydate дата добавления комментария;
Мне кажется в этих двух таблицах все понятно, вопросов быть не должно.
Для администрирования создаем три таблицы: «users», «authorrole», «role».
Таблица «users», будет содержать следующие данные:
id уникальный номер пользователя;
login логин пользователя;
password пароль пользователя;
email адрес электронной почты пользователя;
img адрес расположения аватара пользователя;
activation проверка активации пользователя;
date дата регистрации пользователя.
Для идентификации автора комментария, поле «id» таблицы «users» будет в запросах к бд связываться с полем «userid» таблиц «say» и «reply»
Таблица «role» будет содержать следующие данные:
id роль (права) пользователя;
description описание прав пользователя;
Таблица «authorrole» промежуточная и будет содержать следующие данные:
authorid id пользователя;
roleid роль (права) пользователя;
Таблица «authorrole» связывает пользователей «users» и их права «role»