Классы App и Registry фреймворка
Итак, продолжаем our journey и теперь на повестке дня - написание ядра нашего фреймворка. Это одна из самых сложных частей курса, но без неё не обойтись. В дальнейшем нам будет проще писать код.
В этом посте мы рассмотрим, как создать простой контейнер приложений на PHP, используя паттерн Singleton и регистр свойств. Это может быть основой для вашего блога или другого веб-приложения. Для организации кода мы будем использовать классы, трейты и конфигурационные файлы.
Быстрый обзор необходимых классов
Для начала нам потребуются несколько подготовительных классов, которые станут основными частями нашего фреймворка. В частности, это будет класс App - главный класс, который будет запускать наше приложение.
class App {
// Основные переменные и методы будут здесь
}
В классе App будут инициализироваться контейнер и маршрутизация (раутинг) нашего приложения. Ранее мы обсуждали, что такое маршрутизация. Это ключевая концепция паттерна MVC, которая управляет, куда отправить запрос от пользователя.
В классе App будет происходить запуск маршрутизации и создание контейнера приложения. Контейнер будет реализовывать паттерн Registry, который поясню далее.
class Registry {
// Основные переменные и методы будут здесь
}
Паттерн Singleton
Нам необходимо реализовать паттерн Singleton. Этот паттерн обеспечит создание только одного экземпляра класса для всего приложения.
trait Singleton {
private static ?self $instance = NULL;
private function __construct()
{
// Приватный конструктор
}
public static function getInstance(): static
{
return static::$instance ?? static::$instance = new static();
}
}
Теперь, чтобы реализовать этот паттерн в вашем классе реестра, достаточно использовать трейд:
class Registry {
use Singleton;
private static array $properties = [];
// Методы для работы с свойствами...
}
Создание класса App
Теперь создаём наш класс App:
class App {
public static Registry $container;
public function __construct() {
self::$container = Registry::getInstance();
// Инициализация параметров
$this->initializeParams();
}
private function initializeParams(): void {
// Загрузка параметров из файла и заполнение контейнера
$params = require 'config/params.php';
foreach ($params as $key => $value) {
self::$container->setProperty($key, $value);
}
}
}
Подключение параметров
Создайте файл конфигурации params.php и верните массив с параметрами:
return [
'admin_email' => 'admin.new@blog.loc',
'site_name' => 'My Blog',
'pagination' => 3,
];
В результате, вы сможете получить доступ к параметрам через контейнер:
$adminEmail = App::$container->getProperty('admin_email');
$pagination = App::$container->getProperty('pagination');
Теперь давайте подробно рассмотрим код:
Основные технологии
- PHP: Серверный язык программирования, на котором мы пишем наше приложение.
- Namespaces: Для организации кода и предотвращения конфликтов имен.
- Конфигурационные файлы: Для хранения параметров приложения.
Структура проекта
/vendor
└── /blog
├── TSingleton.php
├── Registry.php
└── App.php
/config
└── params.php
/public
└── index.php
- vendor/blog/: Папка, содержащая классы для нашего приложения.
- config/: Папка с конфигурационными параметрами.
- public/: Папка с доступом к публичным файлам, включая точку входа в приложение.
Разбор кода
1. Трейт TSingleton
namespace blog;
trait TSingleton
{
private static ?self $instance = NULL;
private function __construct() {}
public static function getInstance(): static
{
return static::$instance ?? static::$instance = new static();
}
}
Объяснение:
- Этот трейт реализует паттерн Singleton, обеспечивая наличие лишь одного экземпляра класса и предоставляя глобальную точку доступа к нему.
- Конструктор класса закрыт, что предотвращает создание экземпляров класса извне.
- Метод
getInstance()проверяет существование экземпляра и создает новый, если его нет.
2. Класс Registry
namespace blog;
class Registry
{
use TSingleton;
protected static array $properties = [];
public function setProperty($name, $value)
{
self::$properties[$name] = $value;
}
public function getProperty($name)
{
return self::$properties[$name] ?? NULL;
}
public function getProperties(): array
{
return self::$properties;
}
}
Объяснение:
- Класс
Registryиспользует трейтTSingleton, чтобы гарантировать, что он будет единственным экземпляром. - Он предоставляет методы для установки и получения свойств, что делает его удобным для хранения глобальных настроек и параметров приложения.
3. Класс App
namespace blog;
class App
{
public static $app;
public function __construct()
{
session_start(); // Начало сессии
if (isset($_COOKIE['remember_user']) && !isset($_SESSION['remember_user']['nickname'], $_SESSION['remember_user']['email'])) {
$_SESSION['remember_user'] = unserialize($_COOKIE['remember_user']);
}
$query = trim(urldecode($_SERVER['QUERY_STRING']), '/');
new ErrorHandler();
self::$app = Registry::getInstance();
$this->getParams();
Router::dispatch($query);
}
protected function getParams()
{
$file = CONFIG . '/params.php';
if (is_file($file)) {
$params = require_once $file;
if (!empty($params)) {
foreach ($params as $k => $v) {
self::$app->setProperty($k, $v);
}
}
} else {
echo "Файл по такому пути $file не найден.";
}
}
}
Объяснение:
- Класс
Appуправляет жизненным циклом приложения, включая запуск сессий, обработку куки и загрузку параметров конфигурации. - Метод
getParams()загружает параметры из файла конфигурации и сохраняет их в реестре.
4. Конфигурационный файл params.php
return [
'site_author' => 'Nikolay Ogreba',
'site_avatar' => 'team/admin.jpg',
'site_title' => 'Nikolay Ogreba :: ',
'site_name' => 'Nikolay Ogreba — создание сайтов и заработка на партнёрках',
'pageNotFound' => 'Ой! Ошибка 404',
'admin_author' => 'Nikolay Ogreba',
'defaultPageLimit' => 5, // Default pagination limit
];
Объяснение:
- Этот файл содержит массив с параметрами для приложения. Параметры могут быть расширены по мере развития вашего блога.
- Здесь хранятся такие данные, как автор сайта, аватар, заголовок, название и информация об ошибке 404.
- Конфигурационный файл упрощает управление параметрами, позволяя вносить изменения в одном месте.
5. Файл index.php
public/index.php
new \blog\App(); // Создаем экземпляр приложения
Объяснение:
- Здесь мы подключаем автозагрузчик Composer, который автоматически загружает классы по мере необходимости.
- Создание нового экземпляра класса
Appинициализирует приложение, запускает сессии и загружает параметры.
Использование контейнера
Теперь, когда нам настроен контейнер, мы можем легко обращаться к свойствам приложения в любом месте кода:
// Получение настроек
echo \blog\App::$app->getProperty('site_title'); // Выводит: Nikolay Ogreba ::
\blog\App::$app->setProperty('test', 'TEST'); // Устанавливает новое свойство
var_dump(\blog\App::$app->getProperties()); // Выводит все свойства, хранящиеся в реестре
Заключение
В этом посте мы разобрали, как создать простой контейнер приложений на PHP, используя паттерн Singleton и класс Registry для хранения глобальных параметров. Это позволяет организовать код и упростить управление настройками приложения.
Вы можете расширять функциональность, добавляя новые свойства в реестр, интегрируя обработчики ошибок и маршрутизаторы, а также улучшая ваш блог с помощью новых функций.
Надеюсь, этот разбор кода был полезен и вдохновит вас на создание собственного приложения на PHP! Если у вас есть вопросы или хотите узнать больше о конкретных аспектах кода, не стесняйтесь задавать их в комментариях!
Завершение
В этом уроке мы реализовали базовые части нашего фреймворка и подготовили контекст для написания классов и маршрутизатора в следующих уроках. Убедитесь, что вы внимательно проследили за кодом и его логикой!
Добавить комментарий или задать вопрос ツ
Комментариев нет