Практика PHP для начинающих. Урок 4. Простой маршрутизатор (Router) для MVC
Вставка
- Опубліковано 22 сер 2024
- В данном видео мы напишем самый простой вариант маршрутизатора (Router) для приложения MVC. В дальнейших уроках мы его перепишем, сделаем гибче, благодаря регулярным выражениям, и оформим в виде класса. Но пока простейший вариант, написанный в этом уроке, нам вполне подойдет и на все 100 будет справляться с задачей получения запроса и подключения контроллера, который должен обрабатывать этот запрос.
Данная серия уроков предназначена для начинающих программистов на PHP и веб-разработчиков. Цель предлагаемых уроков - научить писать правильный и красивый код, а также показать основные методики написания структурированного кода. В этих уроках будут затронуты такие темы как:
- Как отделить логику от представления.
- Как избежать дублирования кода.
- Что такое Router (маршрутизатор) и как написать собственный класс Router.
- Как работать с базой данных (БД), используя PDO и как написать свой класс для работы с БД.
- Что такое Service Container и как написать свой Service Container.
- Что такое Middleware и как написать свой Middleware.
- и т.д.
Исходники к уроку - github.com/mat...
Дякую за ще одне супер-корисне відео )
Этот фронконтроллер с роутером на else if крутая штука. Даже простые небольшие сайты можно уже делать смело. Добавление новых разделов сайта облегчается. Else if написал, контроллер, создал, view и уже нормально. Спасибо за замечательный урок
Пожалуйста 🙂
Большое спасибо, что создаете такие подробные видео уроки
Пожалуйста 😉
Спасибо, очень помогли разобраться!
Пожалуйста)
Супер!!! Про тег base не знал. Интересно.
Всегда пожалуйста ;)
Супер, глаза открыли!))
Рад этому))
Не останавливайтесь пожалуйста))
круто!
Отличные уроки. Желаю много подписчиков вашему каналу)
Спасибо :)
Канал отличный!!
@@ijlixt801 спасибо 🙂
Спасибо тебе большое. Круто ты объясняешь. Уроки просто супер
Отличные уроки! спасибо огромное!
Спасибо 🙂
Спасибо за прекрасние уроки!
Пожалуйста 🙂
Прекрасная практика, спасибо большое!🙂
Пожалуйста 😉
спасибо. Огромное спасибо автору!
Крутой урок, СПАСИБО)
Пожалуйста 😉
Уроки топ! Спасибо)
Пожалуйста 🙂
👍👍👍
Классно было бы увидеть на вашем канале подготовку к экзаменам по 1С Битрикс, для разработчиков. Видел Ваши уроки по битрикс на другом канале, если голос не путаю) Просто то что есть на ютубе, оставляет желать лучшего, но как мне кажется тема популярная. Многие компании заставляют проходить эти экзамены для трудоустройства. Я сам работал в такой компании и все сотрудники готовятся по видео с ютуба. В которых я сам находил не одну ошибку, что может повлиять на результат сдачи. С вашей доступной подачей это были бы отличные уроки)
Спасибо)
С 1С-Битрикс работал когда-то, верно. Скорее всего, мои уроки Вы и видели. Но, честно говоря, уже очень давно на практике с ним не сталкивался и практически забыл))) Это разве что по новой его учить...
Like😇
Добрый день Андрей!! Спасибо за видео. Хотел спросить, а как тогда с дублями страниц с такими гет запросами? Или их нужно будет в robots.txt закрывать от индексации?
Добрый день!
1. В последнем видео плейлиста я показываю реализацию ЧПУ, что решает проблему дублей.
2. Также можно использовать канонические адреса с помощью тега link с атрибутом rel="canonical", что как раз и должно решать проблему возможных дублей.
Спасибо за развёрнутый ответ@@matroskin978
Исходники к уроку - github.com/matroskin978/phpbeginners/tree/a42274f625abc2ec3fa579d6c0a2fad7ede29796
Андрей, добрый день! Столкнулся с непонятным чем-то при использовании функции trim при обрезании адресной строки. Если вкратце о проблеме, то trim удаляет символы d, l, r , если они приходятся на конец строки. Например, обрезаю с trim строку '/world/brasil' и получаю brasi!!! Или '/world/poland' и получаю polan. Причем для других строк функция работает исправно. Пробовал и просто строку обрезать, такое же поведение. Дело в версии php или что-то другое здесь? Спасибо!
Добрый день!
Нет, это дело в коде. Функция trim() одинаково работает для всех версий PHP и по умолчанию удаляет пробельные символы. Значимые символы она вообще не трогает, если их не указать вторым параметром.
Вот пример на 3-х версиях PHP (5, 7 и 8):
onlinephp.io/c/07447
Можете запустить этот пример в песочнице. Во всех версиях обе предложенные строки остаются неизменными. Поэтому проверяйте свой код, проблема в чем-то другом.
@@matroskin978 Спасибо за ответ, Андрей!
Уважаемый автор. Возник вопрос.
У меня фавикон не грузиться. Структура папок асболютно та же
а вот с добавлением в путь public/
Возможно, что пропустили в файле .htaccess. Возможно, не включен Apache. Возможно, что-то еще. В уроке все работает. Судя по всему, у других пользователей тоже все ок, потому как никто не писал о подобной проблеме. Поэтому, чтобы ответить наверняка, это нужно смотреть проект на Вашем сервере.
Возможно это от того что Apache + Nginx, нужно оставить просто Apache
@@cascadingresonancesheets кстати, да - очень даже вероятный вариант.
@@matroskin978 Была такая же ерунда, включения только Apache заработало нормально, но для main.css - "У Вас нет прав доступа к этому объекту. Файл недоступен для чтения, или сервер не может его прочитать Error 403"
Андрей, спасибо за урок. Правильно ли я понимаю, что при таком подходе GET параметры залезут в поисковую выдачу?
Пожалуйста)
Параметры при любом подходе могут попасть в индекс. Но это произойдет, если есть ссылка с этими параметрами. Если же ссылки нет, то и параметров лишних Google не будет придумывать.
@@matroskin978 спасибо
@@user-pb9ul3dv7s пожалуйста)
Спасибо, очень круто! Непонятно, зачем делать .htaccess в двух местах если достаточно только в корневой папке написать .htaccess с RewriteRule (.*) public/index.php (а не public/$1 с последующим отлавливанием)? Кто нибудь может пояснить?
Пожалуйста 🙂
Пояснить, конечно же, могу. В принципе, в предыдущем уроке я это уже сделал и даже показал на примере подключения файла стилей.
Смотрите, если использовать Ваш вариант и направить все запросы на файл index.php, тогда на него пойдут как нужные запросы, так и не очень. Например, запросы на подключение файлов стилей, скриптов и картинок. И в результате все это подключено не будет.
Именно поэтому мы направляем вначале все запросы в папку public, а там уже есть дополнительное условие:
RewriteCond %{REQUEST_FILENAME} !-f
которое проверит, что запрашивается не физически существующий файл. Если запрашивается файл - тогда мы пропускаем такой запрос и сервер отдаст файл. Если же это запрос к маршрутизатору, тогда мы его адресуем на index.php.
В корневом файле мы специально не добавляем такое условие, поскольку иначе станут доступны все файлы из корня. Надеюсь, теперь должно быть понятнее 🙂
@@matroskin978 Да, здорово, спасибо огромное! Есть разные варианты в интернете, и когда есть логичное обоснование, почему именно так, а не иначе, это супер! Там, где я видел именно в корневой папке было условие, теперь понятно, что это не очень хорошо.
@@HalizVideo пожалуйста ;)
Добрый день! Спасибо за ваши уроки.
У меня возник вопрос.
На 23:27 вы вызываете $_SERVER[“query string»]
Функция возвращает “about”
Почему результат такой?
Ведь, “about” это путь, а query string тут нету.
Спасибо.
Добрый день!
Через файл.htaccess мы добавляем в запрос путь - это и попадает в query string (строку запроса).
@@matroskin978 спасибо за оперативный ответ! А зачем это нужно?
@@user-wg8sf5pn7z это нужно затем, чтобы по http была доступна только папка public. Именно для этого все запросы направляются в нее корневым файлом .htaccess, а второй файл .htaccess принимает и прикрепляет этот запрос в качестве параметра. Я ведь это все рассказывал в уроке о точке входа))
@@matroskin978 спасибо за ответ!)
Равноценные правила из урока для сервера Nginx. Долго сидел не мог понять, как переписать правила из урока. Гуглил, пересматривал 3 и 4 урок и наконец получилось. Надеюсь кому нибудь поможет. Андрей, спасибо за курс!
location / {
try_files $uri $uri/ @php;
}
location @php {
rewrite ^/(.*) /index.php?$1;
}
location ~ /\. { deny all; }
location = /favicon.ico { }
location = /robots.txt { }
И Вам спасибо за комментарий! Уверен, кому-то точно пригодится ;)
Нашел ошибку, я когда header.php , footer.php, sidebar.php перетаскивал в папку incs , шторм сам такие пути напрописывал - ../../controllers/about.php. Похоже всплывашка в шторме была и я нажал галочку, подтвердить
Ага, супер! Да, редакторы, порой могут еще как "радовать". Вот только сегодня делал урок по OpenCart так там меня VSCode ну прям сильно повеселил свои "умным" дописыванием недостающих тегов))
Такой вопрос, а как вы подключаетесь через 1 папку без "локалхост" в ссылке, это от веб сервера зависит, у меня просто несколько папок и прежде локалхост. Это создает прооблемы с hrefами , тот же $uri содержит не только about а еще 2 папки перед ним ?
Это настройки сервера. Если Вы используете Open Server, тогда в папке domains просто создаете папку, которую хотите видеть адресом локального сайта. Например, у меня в уроке это папка test.loc. После создания папки просто перезапускаете сервер и новый домен будет доступен.
Если используете XAMPP, к примеру, то там все немного сложнее. На канале есть первое видео как раз по настройке XAMPP - там я показываю, как создать домен для этого сервера.
@@matroskin978 То есть если я буду использовать openserver , то смогу подключаться "папка", а не "localhost/папка"?
Точно так)
В конце видео: $_GET и $_SERVER['QUEYR_STRING'] не выводят корректно query string, поэтому добавили флаг [QSA]. Ну и что, что не выводят? Чем это мешает нам? Ведь строка
$uri = trim(parse_url($_SERVER['REQUEST_URI'])['path'], '/');
все равно корректно возвращает массив с корректным URI в элементе path и с корректным query string в элементе query. Чем мы и пользуемся.
Не возражаю против Вашего варианта) Неоднократно говорил и буду говорить, что задачу практически всегда можно решить более чем одним способом. И если Вы решили ее по своему - это ведь отлично!
@@matroskin978 это не мой вариант. это все из вашего видео код
Ок, выберите тогда любой вариант из предложенных.
@@matroskin978 вы вообще не поняли о чем message. ок, проехали
Из Ваших нескольких сообщений к разным урокам мне кажется я прекрасно понял суть Ваших месседжей.
Пока все получилось, но конечно сложно в голове удерживать логику чтобы потом повторить
Попробуйте посмотреть, а затем написать самостоятельно. Если не получится сразу самостоятельно, тогда сделайте текстовые тезизные пометки по пунктам:
1. В таком-то файле делаем такие-то вещи.
2. А в этом - такие.
...
Периодически можно подсматривать на видео сложные моменты. Но после этого все же лучше откатить код и попробовать самостоятельно воспроизвести. Старайтесь понять логику работы приложения, его архитектуру. Это важно, поскольку дальше пойдут более сложные вещи.
Делаю все как в уроке 10:03 выдает ошибку
Fatal error: Uncaught Error: Call to undefined function htth_response_code()
PHP ведь специально пишет подробно, в чем именно ошибка. Не выдает какой-то код, а именно описывает проблему. Чтобы программист мог прочесть ошибку, понять ее и исправить. Вы ошибку прочитали? Попробуйте. Это должно помочь ее исправить. Если все равно не получится - подскажу.
@@matroskin978 Обращение к неопределенной функции htth_response_code(). К сожалению это мне не помогло.
@@ruslan3710 обращение к неопределенной функции значит, что такой функции PHP не нашел. Это может быть в двух случаях:
1. Функция есть, но она недоступна, т.е. файл, в котором эта функция объявлена, не подключен к проекту.
2. Допустили ошибку при вызове. Судя по тексту ошибки, это более вероятный вариант. В тексте ошибки говорится о функции htth_response_code(). Довольно странное название. В коде я называл и вызывал функцию, которая называется http_response_code(). Чтобы было проще найти ошибку в именовании сравните их здесь:
htth_response_code() - так у вас
http_response_code() - так у меня
@@matroskin978 несколько раз переписывал и в итоге заработало, но я так и не понял проблему. Я предполагал но не был уверен. Сейчас вижу. Спасибо.
Пожалуйста ;)
у меня сработал код в таком виде:
if ($uri === ' '){
require_once CONTROLLERS . '/index.php';
} elseif ($uri){
require_once CONTROLLERS . '/about.php';
}
тоесть без === 'about.php' есть ли какая то разница в работе этого кода?
Есть разница, конечно же. И огромная. Блок elseif у Вас будет отрабатывать не только для адреса about, но и для всех прочих адресов. Например, для: about2, about3, test и т.п. А должен отрабатывать только для about.
Добрый вечер. Подскажите пожалуйста, делал все как у вас, кроме что сервера ( у меня Nginx). Сделал так что бы перенаправляло на /public/index.php если страница не найдена. Но возникла проблема с GET запросами. Допустим запрос site/post?id=1 на выходе: $_SERVER['REQUEST_URI'] выводит /post?id=1 $_SERVER['QUERY_STRING'] = " ", $_GET = пустой массив. Может подскажите куда копать.
Здравствуйте!
Копать как раз в сторону сервера, точнее, в сторону правил переадресации. Для того, чтобы GET-параметры не терялись для правила RewriteRule мы использовали флаг QSA. Как это сделать на Nginx - не подскажу.
Может кому-то пригодиться решение. Нужно в конфиге nginx, дописать строчки
location / {
try_files $uri /index.php?$args;
}
После этого будете получать параметры запросов.
@@user-zq4gf6fm7n Привет! Тоже делаю все через Nginx. Можешь помочь разобраться? У тебя при вызове $_GET в этом примере, что возвращается?
Почему у меня строка url такая выходит? practica/controllers/about.php
И работает только так:
elseif ($uri == 'controllers/about.php') {
require CONTROLLERS . '/about.php';
Как отловить такую ошибку?
Не совсем понял... строка url у Вас будет ровно такой, какой Вы ее укажете в ссылке или наберете в адресной строке. К коду эта строка не имеет никакого отношения, поэтому искать какую-то ошибку в коде - смысла нет, если я верно понял суть вопроса.
Если не верно, тогда нужно смотреть Ваш проект. Также можете скачать мой проект и сравнить Ваш код с исходниками. Если все же не разберетесь, тогда скиньте свой проект - я попробую посмотреть.