Этот курс ( Практикум по разработке CMS ) создавался, когда у PHP была версия 5.3 или 5.4. Со временем какие-то функции PHP устаревают (mysql, each), какие-то начинают работать по-другому (empty). Пожалуйста, следите за изменениями в PHP по сайту php.net! |
Обзор технологий. Начало кодирования
Начала навигации. Первые ошибки в работе программы
Обратите внимание на строчку $id = $_GET['id']; в файле index0.php. Эта строчка рассчитана на то, что пользователь из браузера пошлёт на сервер запрос вида http://localhost/index0.php?id=3, а мы на сервере извлечём этот параметр ("3") и используем его для получения нужной строчки таблицы с помощью sql-запроса ("SELECT * FROM `mypages` where id = 3"). То есть мы именно так пока организуем связь запросов клиента и ответов сервера – через параметр id.
Размер нашего кода по сравнению с первоначальным чистым HTML вырос в 3-4 раза. Но на вопрос, стоит ли оно того, здесь быстро ответить нельзя. Для начала надо немного добавить реализма. На сайте редко бывает только одна страница (даже на казалось бы единственной landing-page попросту собрано в кучу много разных страниц). Начнём с двадцати (как будто бы у нас на сайте по астрологии 20 разных страниц). Тогда начальный html-код надо будет размножить на 20 файлов (то есть количество его возрастёт в 20 раз), а последний php-фрагмент у нас находится в единственном файле index0.php и все 20 страниц мы можем вызвать с помощью параметра в адресной строке: http://localhost/index0.php?id=12, http://localhost/index0.php?id=19. Налицо явная экономия, казалось бы.
Но вот с этого места и начинается "экспонента" сложностей. Наш Код в файле index0.php в таком виде попросту не будет работать. Вам это утверждение может показаться слишком сильным. Проверим.
- При переходе по адресу http://localhost/index0.php вы получите сообщение Notice: Undefined index: id in /var/www/html/index0.php on line 2.
- При переходе по адресам от http://localhost/index0.php?id=1 до http://localhost/index0.php?id=20 вы будете видеть какую-то информацию (если вы занесли в таблицу mypages 20 строк, как планировали) – возможно, это будут "кракозябры" или вопросики из-за несоответствия кодировки.
- При параметре id > 20 вы будете видеть пустую страницу (http://localhost/index0.php?id=21).
- И да, во всех случаях вы будете видеть сообщение об ошибке, связанное с установкой часового пояса (если у вас php не очень древний).
- Или вы совсем не будете видеть сообщения об ошибках, а только пустую страницу – что хуже всего в нашем случае.
Вот с последнего и начнём. В работе сайта желательно предусмотреть два состояния: рабочее (для пользователей) и режим отладки. Пользователи не должны видеть всякие notice. Заведём для переключения этого состояния переменную и в зависимости от её значения будем отображать сообщения об ошибках; а для обработки "возражения 4." добавим часовой пояс по умолчанию (листинг 1.6 пример 1.6):
<?php $debug = true; error_reporting(E_ALL); ini_set('log_errors', true); ini_set('display_errors', $debug); date_default_timezone_set('Asia/Yakutsk'); //... ?>Листинг 1.6.
Добавьте этот код к первоначальному php-коду и сохраните в Папке сайта под именем index1.php. Проверьте код, он должен выглядеть примерно так: http://nichtig.ru/index1.php?code. Чтобы при добавлении параметра "code" можно было видеть php-код файла (вместо результата работы программы) мы использовали дальше следующий фрагмент:
<?php //... if (array_key_exists('code', $_GET)) { header('Content-Type: text/html; charset=UTF-8'); $code = file_get_contents(__FILE__); highlight_string($code); exit; } //... ?>
Это было самое простое. Дальше будет всё хуже и хуже. Каждый раз, когда вы обращаетесь к переменной по её имени (например, к переменной $debug в конструкции ini_set('display_errors', $debug);), вы должны ожидать неприятностей разного рода:
- переменная не существует;
- тип переменной не соответствует ожидаемому;
- значение переменной не соответствует ожидаемому диапазону.
Все эти случаи надо предусматривать и "обрабатывать" – закладывать в программу возможность исправить ситуацию до такой степени, чтобы обычный пользователь ничего не заподозрил (а думал, что так оно и планировалось), или доводить ситуацию хотя бы до внятного сообщения об ошибке (в режиме debug).
Проблема 2 – одна из самых неприятных: в php действует "незаметное" приведение типов к нужному (в данном месте кода), и программист быстро привыкает особо не обращать внимания на типы, что иногда внезапно вылезает боком (например, при попытке обратиться к элементу массива по индексу – $arr[1] – когда переменная $arr не является массивом).
Проблема 1 уже встретилась нам при обращении к странице index1.php без параметра ("Notice: Undefined index: id..."). Проблема 3 – при попытке вызвать страницу с id > 20. Решение этих проблем не является тривиальным, так как зависит совсем не от программиста. Как именно следует их решать, должен сказать владелец сайта, но он не подозревает об этих проблемах, и возникает замкнутый круг, разорвать который можно только путём долгих и мучительных переговоров – поэтому на большинстве сайтов эти проблемы вообще не решаются никак (либо решаются путём банального отключения сообщения об ошибках).
Проблему 1 мы решим с помощью следующей конструкции (листинг 1.7 пример 1.7):
<?php $id = isset($_GET['id']) ? $_GET['id'] : 1; ?>Листинг 1.7.
Если посетитель сайта не обращается к нашей таблице явно по id, нам всё равно нужно выдать ему какие-то значения по умолчанию, введённые владельцем сайта в таблицу под тем номером, который он сообщит программисту. Мы делаем допущение, что этот номер – 1, то есть обратившись к адресу index1.php без параметра id, пользователь увидит запись с id = 1.