Это серия статей о том, как определенные, очень распространенные функции и аспекты популярных фреймворков PHP можно реализовать самостоятельно, не полагаясь на фреймворк. Я надеюсь, что здесь я покажу некоторые передовые методы, которые вы можете использовать в своих приложениях/проектах, не полагаясь на огромную платформу для этого.
Очень распространенный способ разработки простых PHP-приложений состоит в том, чтобы просто написать каждую страницу в виде .php
файла. Таким образом, у вас будет стандартный файл index.php
в качестве «домашней» страницы, а затем ссылки на другие файлы, каждый из которых по отдельности отображает другие ваши страницы.
Хотя это нормально для простых приложений, особенно тех, которые на самом деле состоят только из пары файлов PHP верхнего уровня, для более крупных приложений это становится утомительным, а также снижает гибкость ваших URL-адресов. Как вы могли заметить, если вы использовали их раньше, многие фреймворки (Symfony, Laravel и т. д.) не создают отдельные сценарии для каждой страницы, а вместо этого имеют механизм «маршрутизации», в котором вы определяете все свои URL-пути. в коде, и фреймворк волшебным образом обработает связь между ними и создаст правильный код для этого маршрута на основе предоставленного URL-адреса.
Этот подход к приложениям намного приятнее, потому что поток вашего приложения намного легче отслеживать и рассуждать; каждый запрос начинается с одного и того же места. Вам также больше не нужно include
копировать кучу файлов или запускать/возобновлять сеансы на каждой отдельной странице. Вместо этого вы можете выполнять такие действия, как автоматическая загрузка, создание экземпляра сеанса и т. д., всего один раз.
Вот краткое руководство о том, как две функции PHP ($_SERVER
superglobal и автозагрузка) позволяют определить единую точку входа для всех запросов к вашему приложению.
$_SERVER[‘PATH_INFO']
Как и большинство PHP-сайтов, мы начнем с простого index.php
и будем двигаться дальше. Скопируйте следующую суть в файл index.php
в любом каталоге, который вы хотите.
Современные версии PHP фактически включают в себя веб-сервер, который вы можете вызывать из командной строки. Итак, чтобы протестировать этот файл, давайте воспользуемся им сейчас. cd
в каталог, где вы записали этот index.php
, а затем выполните следующую команду:
php -S localhost:8080
Теперь вы сможете перейти в свой веб-браузер, загрузить https://localhost:8080
и увидеть что-то похожее на следующее:
Это меньше, чем интересно. Но если мы добавим больше в наш URL-путь, мы должны увидеть, что то, что выводится на экран, меняется вместе с ним. Например, если я вставлю этот URL-адрес https://localhost:8080/this/is/a/tutorial
, я получу:
Используя эту константу сервера PATH_INFO
, мы можем получить значение URL, указанного в запросе к нашему серверу в коде. Есть много других полезных суперглобальных переменных, которые мы можем использовать для конкретизации наших приложений. Основные, с которых я рекомендую начать, это $_SERVER
и $_REQUEST
.
Вы можете заметить, что в суперглобальной переменной $_SERVER
также есть значение REQUEST_URI
. Разница между REQUEST_URI
и PATH_INFO
заключается в том, что REQUEST_URI
содержит полный текст URL-адреса, тогда как PATH_INFO
опускает строку запроса. Например, для URL https://localhost:8080/hello?name=kyle
$_SERVER[PATH_INFO]
имеет значение /hello
, тогда как $_SERVER[REQUEST_URI]
имеет значение /hello?name=kyle
. Для маршрутизации достаточно PATH_INFO
.
Теперь, когда у нас есть способ получить доступ к этой информации о пути, мы можем фактически начать использовать ее значение для принятия решений о том, как мы обслуживаем запрос. Для этого примера предположим, что у нас есть две страницы: /home
и /about
, и мы хотим показать разную информацию на каждой из них. Внося следующие изменения в наш index.php
, мы фактически получаем разные выходные данные в зависимости от пути. И мы по-прежнему используем только один файл PHP.
Автозагрузка
Следующей частью приложений PHP с единой точкой входа является использование автозагрузки. При программировании с одним скриптом на странице вам часто приходится иметь кучу require_once
в верхней части ваших скриптов для импорта таких вещей, как классы утилит, шаблоны, другие маршруты и т. д.
Это становится утомительным и повторяющимся и поощряет плохую структуру, поскольку вы хотите вызывать эти require
как можно реже (также вызывает ошибки, когда вы забываете их добавить). Гораздо более лаконичный способ сделать это называется автозагрузкой. Автозагрузка работает путем динамического поиска и загрузки необходимых классов при их создании.
Если вы создаете экземпляр класса несколько раз, автозагрузчик уже сохранил его в памяти, и ему не нужно полностью анализировать и проверять другой файл, чтобы узнать, был ли он уже загружен. Это также позволяет вам просто использовать классы, как если бы они повторно всегда включены.
Важное примечание: это не замена пространства имен, и вы все равно должны использовать использование пространства имен и операторов use
. Автозагрузка предназначена только для фактического импорта фактического исходного кода PHP в ваше приложение.
Composer — очень популярное решение для управления зависимостями для PHP-приложений, использующее автозагрузку. Для этого урока излишне устанавливать и включать композитор, когда нам действительно нужна его функция автозагрузки. Итак, давайте просто сделаем это сами. Честно говоря, это очень просто для того, насколько просто наше приложение на данный момент. Просто измените начало вашего index.php
, чтобы оно выглядело следующим образом:
Функция spl_autoload_register
динамически находит и загружает файлы, содержащие наши PHP-классы, по мере необходимости. По умолчанию это делается путем предположения, что ваша структура пространства имен отражает файловую структуру вашего проекта. например глобальное пространство имен (пустая строка) находится в каталоге верхнего уровня, каждое пространство имен имеет каталог на верхнем уровне, подпространства имен имеют подкаталоги и т. д. Если я вызываю new Classes\A()
, spl_autoload
предполагает, что у меня есть каталог верхнего уровня Classes
с файлом A.php
внутри него. Если я вызову new Classes\Subclass\A()
, он просматривает каталог верхнего уровня Classes
, подкаталог Subclass
, а затем файл A.php
в нем.
Учитывая, что это логичный способ изложить структуру вашего проекта, реализация по умолчанию на самом деле работает большую часть времени. Одна вещь, которую вы можете сделать, чтобы расширить эту функциональность, — написать свой собственный автозагрузчик, если вы хотите следовать другой иерархии каталогов проекта (или вы являетесь Composer и вам нужно управлять структурой каталогов для всех проектов поставщиков). Подробнее об этом можно прочитать на странице документов для spl_autoload_register
.
На данный момент это ничего не делает для нас, так как у нас есть только один файл .php
. Чтобы реорганизовать это и фактически использовать автозагрузку, мы можем создать новый About.php
и новый Home.php
и переместить соответствующий код в эти файлы. Теперь наш проект выглядит так:
Теперь при создании экземпляра index.php
, в зависимости от пути запроса, PHP встретит AboutPage
, HomePage
или просто echo
. В старые времена require
нам приходилось require_once
и AboutPage
, и HomePage
, и они оба загружались при каждом вызове скрипта (или помещали require_once
прямо перед созданием экземпляра класса, но это плохая практика). Однако при автозагрузке это включение является динамическим. Таким образом, если /home
— это путь запроса, AboutPage
никогда даже не загружается в наш проект. Если мы сталкиваемся с сообщением 404, мы не загружаем какие-либо другие файлы. Мы не только получаем удобство от того, что не нужно включать кучу операторов require
, но также ускоряем время выполнения, поскольку нам не нужно анализировать и загружать каждый файл для каждого запроса.
Подведение итогов
Самостоятельный анализ пути запроса и использование автозагрузки — это два очень простых метода, которые вы можете использовать, чтобы получить множество основных функций, которые предоставляют большие, мощные фреймворки. Если, например, вы использовали Laravel только из-за удобной маршрутизации, теперь вы вырезали всю огромную зависимость. Точно так же, если вы использовали Composer только из-за его функции автозагрузки, он вам больше не нужен для простых проектов!
Удаление слоев фреймворков и библиотек, которые часто используют начинающие программисты во всех случаях, — это очень простой способ сократить количество зависимостей и узнать больше о возможностях языка, о которых вы, возможно, не знали. Эти основные фундаментальные концепции могут быть наслоены и расширены по вашему желанию. Кроме того, когда вы впервые читаете новую кодовую базу только для того, чтобы обнаружить, что они не используют выбранный вами фреймворк, вы знаете, на что нужно обращать внимание, чтобы лучше понять, что на самом деле происходит в коде.
Надеюсь, вам понравился этот урок. Если у вас есть какие-либо вопросы, не стесняйтесь комментировать ниже или пишите мне в личку на Reddit: u/Kilenaitor. Спасибо за чтение!
Ниже я представил более сложную схему того, как могло бы выглядеть простое PHP-приложение, использующее преимущества единой точки входа. Не стесняйтесь проверять это, создавать ответвления, настраивать, улучшать и т. д.