Вводное занятие

С последнего курса по разработке сайтов прошло уже больше полугода, так что настало время запустить еще один.
На этот раз мы познакомимся с работой на чистом PHP, без уютной админки и набора готовых инструментов. Мы напишем свой собственный мини-движок, который будет уметь разбирать запросы от пользователей и выводить страницы сайта. Конечно, мы будет стараться писать его красиво и логично, чтобы наш движок можно было расширять.
Хочу предупредить вас сразу, что я не считаю себя экспертом в программировании. По образованию я врач-эпидемиолог, и программирование в медицинской академии не преподавали. Всё, что я знаю, я освоил сам по книжкам и "методом тыка".
Люди, уже программирующие на PHP, из этих уроков ничего нового не вынесут (ну, может что-то и подсмотрят любопытное, но не факт), так что курс будет интересен исключительно новичкам. Я рассчитываю на то, что вы знаете только базовые функции PHP и умеете писать простейший спагетти-код, то есть PHP вперемешку с HTML и выводом через echo().
Тот мини-движок, который мы напишем, можно будет использовать в реальной работе, но он явно не будет лучшим решением среди всех готовых. Его задача - проиллюстрировать курс, а не написать мега-инструмент для работы.
Первое занятие бесплатное, а дальше будет нужно купить доступ. Всё уже открыто бесплатно.

Хостинг

Первым делом нам нужно определиться с хостингом. Подойдёт абсолютно любой, который умеет выполнять PHP и работает с MySQL. Я буду пользоваться https://modhost.pro на тарифе "Минимальный". Хоть этот хостинг и рассчитан на MODX, там есть возможность создавать пустые сайты, без движка.
Вы можете выбрать любой удобный для вас хостинг, единственное пожелание - не использовать Windows сервера, чтобы не было неприятных сюрпризов с отсуствием поддержки каких-нибудь модулей.
На веб-сервере мы настраиваем работу ЧПУ. Если это nginx, то нужно задать в нём вот такие правила (на modhost.pro они включены по умолчанию):

location @rewrite {
    rewrite         ^/(.*)$ /index.php?q=$1;
}

location / {
    try_files       $uri $uri/ @rewrite;
}
А на Apache2 вот такое:

RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
Суть их работы в том, чтобы все запросы по несуществующим адресам на сайте отправлять на index.php - там мы их будем ловить и обрабатывать.
На настройке подключения к серверу я останавливаться не буду, вы уже должны это знать. Если же нет, то почитайте вот в этой заметке. Как и раньше, я советую всем использовать для работы IDE PhpStorm.

Пишем index.php

Первым делом нам нужно написать основной файл для приёмки запросов, который принято называть index.php.
По традиции, создаём index.php корне сайта с таким содержимым:

<?php

echo 'Hello World!';
И проверяем, чтобы он открывался на сервере. Лично я открываю сайт http://s1889.bez.modhost.pro. Если всё ок - продолжаем. Если нет, начинаем задавать вопросы в комментариях.
Мы хотим написать хороший движок, поэтому в index.php сразу добавляем вывод всех ошибок на экран:

ini_set('display_errors', 1);
ini_set('error_reporting', -1);
Index.php должен принимать все запросы, которые будут отправляться на сайт. Вообще все, то есть в деле обработки запросов он самый главный. Именно он определяет, что запросили и что нужно показать в ответ.
Поэтому, он должен анализировать массив $_REQUEST, в котором находятся все данные, присланные пользовательским браузером. Чтобы их увидеть, делаем так:

<?php

echo '<pre>';
print_r($_REQUEST);
Вот этот вот метод с распечаткой массива после вызова тега pre мы будем использовать очень часто, как средство простейшей диагностики.
Вот что должно быть на экране:

Array
(
)
Негусто, да? Ну так мы ничего и не запросили. Давайте откроем укажем в URL параметр ?id=1 и увидим:

Array
(
    [id] => 1
)
Вот и первый запрос на наш сайт. Index.php уже может что-то на него ответить, если захочет. Как видите, данные приходят в пеерменную q, которую мы ранее указали в настройках веб-сервера.
Давайте теперь оформим первисное подобие ЧПУ, которое будем развивать на следующих занятиях:

// Массив доступных страниц
$pages = array('home', 'test');
// Определяем страницу для вывода
$page = '';
// Если запрос не пуст - проверяем, есть ли он в массиве наших страниц
if (!empty($_REQUEST['q'])) {
    $request = explode('/', $_REQUEST['q']);
    // Если есть - окей, всё верно, используем это имя
    if (in_array(strtolower($request[0]), $pages)) {
        $page = strtolower($request[0]);
    }
}
// Иначе используем страницу по умолчанию
if (empty($page)) {
    $page = 'home';
}

echo "Мы выводим страницу <b>{$page}<b>";
Теперь мы можем хапрашивать адреса http://s1889.bez.modhost.pro/ и http://s1889.bez.modhost.pro/test/ и видить, что текст меняется.
Мы написали простейший роутер для ЧПУ.

Заключение

На следующем занятии мы начнем осваивать объектно-ориентированное программирование для написания основного класса с ядром системы, а также напишем первый контроллер страницы.
Дальше будет простенький шаблонизатор и вывод первых документов пользователю по запрошенным url.
Все изменения я буду сохранять на GitHub, чтобы давать ссылки на код урока. Например, сегодня мы написали вот это.

10 комментариев

Поддерживаю!!! Молодец!!!
Wassi Wassinen
Основы - это хорошо.
Василий, установи OrphoMan, чтобы очепятки присылать удобно было.
Дмитрий Алпатов
Василий, добрый день! Хочу взять консультацию по скайпу. Есть еще такая возможность?
Василий Наумкин
Неа
Дмитрий Алпатов
Жаль. Спасибо за сайт и всю ту работу, которая тобой сделана! Огромное количество полезных материалов.
Василий Наумкин
Вопросы можно задавать на https://modx.pro
Александр
а есть какая то единая оплата за курсы ???
Василий Наумкин
В смысле?
Сейчас пока только один курс платный - последний, про чистый PHP. Первые два открыты для всех.
Александр
Ничего если я буду задавать глупые вопросы? Можно вместо
$page = '';
присваивать сразу дефолтное значение
$page = 'home';
чтобы не делать проверку в конце? Или это несет с собой какие-то подводные (для меня) камни?
Василий Наумкин
Можно !
bezumkin.ru
Personal website of Vasily Naumkin
Прямой эфир
Василий Наумкин
01.07.2024, 11:56:41
Да, верно, именно так. А в контроллере, скорее всего, ловить данные методом post.
Василий Наумкин
26.06.2024, 09:38:15
О, точно, вылезает если не залогинен. Спасибо, исправил!
Василий Наумкин
09.04.2024, 04:45:01
> Ошибка 500 Это не похоже на ошибку Nginx, это скорее всего ошибка PHP - надо смотреть его логи. ...
Futuris
04.04.2024, 08:56:12
Я просто немного запутался. Когда в абзаце "Vesp/Core" ты пишешь про "новый trait FileModel", я поду...
Василий Наумкин
20.03.2024, 21:21:52
Volledig!
Андрей
14.03.2024, 13:47:10
Василий! Как всегда очень круто! Моё почтение!
russel gal
09.03.2024, 20:17:18
> А этот стоило написать хотя бы затем, чтобы получить комментарий от юзера, который ничего не писал...
Александр Наумов
27.01.2024, 03:06:18
Василий, спасибо! Извини, тупанул.
Василий Наумкин
22.01.2024, 07:43:20
Давай-давай!
Василий Наумкин
24.12.2023, 14:26:13
Спасибо!