PHP Микрофреймворк HLEB

Скачать Скачать c GitHub
Предназначение Установка Настройка Структура проекта Маршрутизация Типы маршрутов Группы маршрутов Защита маршрутов Конструктор страниц Контроллеры Модели Получение данных Базы данных Дополнительно

Дополнительно

Установка и обновление: использование Composer

Маршрутизация: установка формата для адреса

Маршрутизация: использование переменных в файлах роутов

Маршрутизация: работа с поддоменами

Использование отладочной панели Debug Panel

Маршрутизация: регулярное выражение для динамических значений

Шаблоны: использование includeTemplate

Шаблоны: кэширование при помощи includeCachedTemplate

Консоль: использование собственных консольных команд

Admin Panel: простая административная панель

Radjax: быстрый вспомогательный роутер

Установка и обновление: использование Composer

Установить актуальную версию проекта при помощи консольной команды (требует установленный менеджер пакетов Composer):
$ composer create-project phphleb/hleb
Обновить только ядро фреймворка (выполнить из папки с установленным проектом):
$ composer require phphleb/framework
Обновить все установленные зависимости:
$ composer update

Маршрутизация: установка формата для адреса

Переданные с контроллером значения можно использовать для различных целей, например, для назначения локали и/или формата данных.
Route::get('/get_data/')->controller('AjaxTestController@data', ['json', 'en']);
Переданный формат данных может быть использован для установки Content-Type, так запрос формата json изменит Content-Type в application/json.
// Файл /app/Controllers/AjaxTestController.php ... function data($format, $locale) { ... } ...
Реализация подобного назначения формата для группы маршрутов:
Route::before('SetHeadersBefore@contentType', ['json'] ); Route::getGroup(); Route::get( ... ); Route::get( ... ); Route::endGroup();

Маршрутизация: использование переменных в файлах роутов

Так как карта маршрутизации содержит обычный код PHP, то допустимо использовать все его возможности с единственным ограничением: без использования внешних данных. Например, задание переменных:
$page = "test"; Route::get("/$page/first/", ... ); Route::get("/$page/second/", ... );
В данном примере на практике уместнее было бы использовать префикс группы. Однако, вынос значений в переменные может привести к созданию универсального шаблона маршрутов для использования в дальнейшем.

Маршрутизация: работа с поддоменами

Задать правила для поддоменов, а также, при надобности, для домена любого уровня, помогут два метода маршрутизации: domain() и domainTemplate().
Route::domain("dev")->getGroup(); Route::get("/", ... ); // dev.site.com или *.dev.site.com Route::endGroup(); Route::get("/", ... ); // все запросы (site.com или *.site.com)
Второй параметр в этих методах указывает на соответствие уровню домена, начиная от домена верхнего уровня (1), домена (2) и поддоменов (3 по умолчанию и далее), а первый аргумент может быть перечнем допустимых значений. Например:
Route::domain("sub4", 4)->domain("sub3")->get("/", ... ); // sub4.sub3.site.com или *.sub4.sub3.site.com Route::domain(["var1", "var2", null])->get("/", ... ); // var1.site.com, var2.site.com или site.com, а также *.var1.site.com или *.var2.site.com
Route::domain(null)->get("/", ... ); // без поддоменов, только site.com Route::domain("sub4", 4)->domain("*")->get("/", ... ); // sub4.*.site.com или *.sub4.*.site.com // метод domain("*") добавлен для наглядности маршрута, его можно не указывать
Так как в этих примерах адрес роута одинаковый ("/"), то следует обратить внимание на очередность роутов, будет выбран первый совпавший по URL, поэтому рекомендуется сначала располагать частные случаи, а затем общие.

Привязка маршрутов осуществляется без формального разделения на домен и поддомены, только по уровням иерархии доменного имени, начиная от домена верхнего уровня. В комментариях к этим примерам "site.com" аналогичен любым вариантам домена второго и первого уровня.

Метод domainTemplate() отличается только тем, что в первом аргументе передаются значения для проверки на совпадение в регулярном выражении.

Для кириллических поддоменов возможно придётся задавать условия только после конвертации названия поддоменов в Punycode.

Использование отладочной панели Debug Panel

В микрофреймворк HLEB добавлена отладочная панель, активная только в DEBUG-режиме. Она подключается при помощи строки:
// Файл /app/Optional/MainConnect.php ... [ "Phphleb\Debugpan\DPanel" => "vendor/phphleb/debugpan/DPanel.php" ] ...
После подключения можно настроить эту панель, добавив собственные данные для вывода, используя методы классов \Hleb\Main\MyDebug и \Hleb\Main\WorkDebug.

MyDebug

Создав класс FirstBefore или любым подобным способом:
// Файл /app/Middleware/Before/FirstBefore.php namespace App\Middleware\Before; use Hleb\Main\MyDebug; class FirstBefore extends \MainMiddleware { function index() { MyDebug::add("SERVER", $_SERVER ?? []); MyDebug::add("SESSION", $_SESSION ?? []); MyDebug::add("REQUEST", $_REQUEST ?? []); // Пример последовательного добавления if (isset($_COOKIE)) { foreach ($_COOKIE as $key => $value){ MyDebug::insert_to_array("COOKIE", "<b>$key</b>: " . $value); } } } }
Первым аргументом здесь указывается желаемое название вкладки, при этом для MyDebug::add() вторым параметром обязателен массив, а для MyDebug::insert_to_array() второй аргумент - любое значение, добавляемое в массив по имени. Также можно использовать метод MyDebug::insert_to_string(), в котором вторым аргументом добавляется строковое значение.

Теперь в отладочной панели появятся четыре дополнительные вкладки с параметрами, при условии, что этот класс подключён в карте маршрутов перед проверяемыми маршрутами.
Route::before('FirstBefore')->getGroup(); Route::get('/', 'Данные выведены в панель отладки.'); ... // Распространить правило на подключаемый файл include 'other_routes.php'; Route::endGroup();
Применение класса WorkDebug аналогично MyDebug, только служит для временного вывода данных при помощи var_dump, которые размещаются поверх страницы в отдельной панели. Отладочные данные этих классов доступны для добавления везде в проекте, кроме After-классов, которые выполняются после вывода основного контента.
\Hleb\Main\WorkDebug::add($data);
// Равносильно print_r2($data);
// С описанием \Hleb\Main\WorkDebug::add($data2, 'Описание data2');
Более простым и запоминающимся аналогом для вызова WorkDebug::add() является функция print_r2() c такими же аргументами.

Маршрутизация: регулярное выражение для динамических значений

Регулярное выражение в методе where() может принимать различные условия, в рамках правил составления регулярных выражений, например:
Route::get('/{page}/', 'Все вхождения по условию, кроме /map/.')->where(['page' => '(?!(map))[a-z0-9\-_]+']); Route::get('/map/', 'Отдельная обработка /map/.');
Данный пример не совсем отвечает интуитивно понятному способу составления карты маршрутов, в реальном проекте лучше определить эту закономерность при помощи очередности поиска подходящего маршрута:
Route::get('/map/', 'Отдельная обработка /map/.'); Route::get('/{page}/', 'Все вхождения по условию, кроме /map/.')->where(['page' => '[a-z0-9\-_]+']);

Шаблоны: использование includeTemplate

Части кода в подключаемых файлах папки views могут повторятся. Чтобы вынести их в отдельный шаблон, независимый от окружающего контента, используется функция includeTemplate(), первым аргументом которой указывается название шаблона из папки resources/views, а вторым - массив переменных, которые будут доступны в шаблоне по ключам массива. Для отличия шаблонов от других файлов их рекомендуется разместить в отдельной папке templates.
// Файл /resources/views/content.php includeTemplate('templates/name', ['p1'=>'data1', 'p2'=>'data2']);
// Файл /resources/views/templates/name.php echo $p1; // data1 echo $p2; // data2

Шаблоны: кэширование при помощи includeCachedTemplate

В отдельных случаях, если содержимое шаблона требует существенных расчётов, но данные неизменны некоторое время, есть возможность задать кэширование. Чем больше производительности требуют эти вычисления, тем больший прирост в скорости обработки блока можно получить при последующих обращениях, так как в кэше он сохранен как обычный html-текст.
Кэширование будет привязано к пользовательской сессии и заданному времени в методе setCacheTime(), который необходимо расположить в шаблоне includeCachedTemplate(). Аргументы последнего индентичны функции includeTemplate(), единственное отличие, что заданное в шаблоне время кэширования приведет к кэшированию содержимого. Все изменения содержимого для конкретного пользователя будут недоступны до истечения указанного срока. Также следует учесть, если шаблон задан через функцию includeCachedTemplate() и в нём установлено время кэширования, то где бы он не был использован в проекте, кэшированное значение его будет для текущего пользователя одинаковым.
// Файл /resources/views/content.php includeCachedTemplate('templates/cached/name');
// Файл /resources/views/templates/cached/name.php $this->setCacheTime(60); // задание времени кеширования в секундах echo rand(); // рандомное число будет неизменно в течении минуты

Кэширование должно быть рационально и обдуманно в каждом случае, иначе результат может слишком явно не соответствовать вычисляемым данным. Например, рекомендуется кэшировать блоки, содержащие информацию, которая рассчитывается из текущего названия месяца или ежедневно обновляемого курса валют. Но и в таком случае значение желательно устанавливать не более 10 минут (600 секунд).
Если это определение без особых затрат производительности, вроде прямого получения даты из PHP-функции date(), то эффективности от кэширования не будет.

Также при использовании дополнительно передаваемых параметров, через функцию includeCachedTemplate(), возможно отсутствие пользы от кеширования, если эти параметры часто изменяются. В случае возникновения каких-либо сомнений при использовании этой функции, лучше заменить её на функцию includeTemplate().
Для удаления всего кэша шаблонов - удалить содержимое папки /storage/cache/templates/.

Консоль: использование собственных консольных команд

Перечень встроенных консольных команд отображается командой php console --help, выполненной в корневой директории проекта.
$ php console --help
--version or -v (версия фреймворка)
--clear-cache or -cc (очистка кэша шаблонов и маршрутов)
--info or -i (вывод настроек)
--help or -h (помощь)
--routes or -r (вывод списка маршрутов)
--list or -l (вывод списка пользовательских команд)

Создать собственную консольную команду при помощи добавления соответствующего класса в app/Commands/:
// Файл /app/Commands/DefaultTask.php namespace App\Commands; class DefaultTask extends \MainTask { // php console default-task [arg] const DESCRIPTION = "Default task"; // Короткое, но информативное описание команды. protected function execute($arg = null) // Переменная $arg будет содержать необязательный дополнительный аргумент. { // Содержимое класса } }
Теперь можно вызвать эту команду по принципу соответствия DefaultTask > default-task.
$ php console default-task
Если, например, класс расположен в папке app/Commands/Folder/, то вызвать его можно таким образом:
$ php console folder/default-task
Стоит учесть, что при расположении класса в папке app/Commands/Folder/, его namespace должно быть App\Commands\Folder.

Добавление произвольного значения "test", которое будет передано в переменной $arg :
$ php console default-task test


Admin Panel: простая административная панель

В версии 1.1.5 фреймворка добавлен новый метод маршрутизации adminPanController(). Он необходим для использования библиотеки phphleb/adminpan, которая подключается отдельно.
$ composer require phphleb/adminpan
Метод adminPanController() аналогичен методу controller(), с той разницей, что отображаемый им контент будет встроен в оболочку административной панели.
Route::get('/admin/panel/main/')->adminPanController('AdminController@main', 'Page Name');
Следует использовать только прямые указания пути для маршрутов данного контроллера, чтобы в его меню правильно отображались ссылки на другие роуты adminPanController() и названия ссылок (в примере выше это "Page Name").
К странице в дальнейшем допустимо подключить какой-нибудь СSS- и/или JS-фреймворк в коде подключаемого контента.

Кроме того, можно воспользоваться встроенными инструментами формирования таблиц и списков.
// Файл /app/Controllers/AdminController.php namespace App\Controllers; use Phphleb\Adminpan\MainAdminPanel; class AdminController extends \MainController { function main() { $panel = new MainAdminPanel(); // Вывод HTML $content = $panel->getDataHTML("<b>HTML</b>");
// Вывод нумерованного списка $content .= $panel->getDataList(["Text 1", "Text 2", "Text 3"]);
// Вывод массива с данными в виде таблицы $data = UserModel::getData(); $content .= $panel->getDataTable($data);
return $content ; } }
Таким же образом методы класса MainAdminPanel доступны в view-файлах, возвращаемых из контроллера функцией view().


Radjax: быстрый вспомогательный роутер

Данный маршрутизатор не включен в основной пакет фреймворка, его можно установить через Composer:
$ composer require phphleb/radjax
После установки остается только назначить роуты в файле /routes/ajax.php или /routes/api.php проекта. Эти роуты просты и отличаются от роутов фреймворка HLEB. В них присутствует один метод get(), через который и настраивается конфигурация. Следует отметить, что, кроме этих отличий, есть ещё несколько:

1) Если тип маршрута (GET, POST и тд.) из конфигурации не подходит, нo адрес маршрута совпал, Radjax-роутер не пропустит поиск далее, как это реализовано во фреймворке, а выдаст ошибку 405 (метод не поддерживается) c перечислением корректных для этого маршрута типов в заголовке.

2) Константы для настроек фреймворка никак не влияют на работу Radjax-роутера, он функционирует независимо и запускается отдельно от фреймворка, из-за чего его производительность выше. В большинстве, от роутера такого типа, требуется только получить или сохранить данные по запросу и отобразить ответ в виде json или xml.

3) Radjax может проверять токен, генерируемый фреймворком для защиты от CSRF-атак, если включен параметр protected данного роутера, но не устанавливает токен самостоятельно. Поэтому, используемый для ajax-запросов роутер проверяет существующий токен, как минимум уже установленный в сессию на странице, с которой был выполнен запрос. При использовании роутера как API, параметр protected следует отключить, чтобы сторонние ресурсы могли запрашивать данные. Дубликат токена для проверки добавляется со страницы GET- или POST-параметром "_token".

4) Файл /routes/ajax.php или /routes/api.php может включать только специальные роуты Radjax, эти файлы не нужно инклюдировать в файл /routes/main.php, как в случае с другими файлами роутинга фреймворка.

5) Класс контроллера указывается полностью, вместе с его namespace, например, "App\Controllers\Api\MainController", а при не обнаружении метода класса, указанного после знака "@", поиск продолжается по указанному методу с добавлением приставки "Http{Type}", где Type это текущий тип HTTP запроса. Например, для "App\Controllers\Api\MainController@test" и указанием поддерживаемого типа ["post"], в соответствующем классе сначала будет произведен поиск метода test(), а если он не будет найден, то testHttpPost().

6) По умолчанию реализовано чтение файлов сессий, но не их сохранение, это улучшает обработку конкурентных ajax-запросов. Однако, возможность сохранения изменений в сессию можно включить в конфигурации роута, указав "save_session" => true.

Radjax\Route::get('/customers/{number}/orders?/', ["get","post"], "App\Controllers\CustomersController@orders", ["protected" => true, "where"=>["number" => "[0-9]+"], "save_session" => false]);
Как видно из примера, первым параметром идёт адрес роута, в нём значение number динамическое и доступно из Request::get("number"), а знак "?" после orders обозначает, что эта часть адреса не обязательна для совпадения. Вторым параметром указан массив с типами HTTP-запроса, на третьей позиции класс контроллера и метод класса, четвертым аргументом включён массив необязательных именованных параметров.




Предназначение Установка Настройка Структура проекта Маршрутизация Типы маршрутов Группы маршрутов Защита маршрутов Конструктор страниц Контроллеры Модели Получение данных Базы данных Дополнительно


HLEB - PHP Микрофреймворк Свободная лицензия. Без гарантий. © fomiash 2019