ADR-005 - PSR-15 Шаблон проміжного програмного забезпечення
ADR-005: шаблон проміжного програмного забезпечення PSR-15 для XOOPS 4.0
Section titled “ADR-005: шаблон проміжного програмного забезпечення PSR-15 для XOOPS 4.0”Використовуйте обробники запитів HTTP-сервера PSR-15 (проміжне програмне забезпечення) для покращеного конвеєра обробки запитів.
:::обережно[XOOPS Пропозиція 4.0 — Недоступно в 2.5.x]
Цей ADR описує пропоновану архітектуру для XOOPS 4.0. Проміжне програмне забезпечення PSR-15 недоступне в XOOPS 2.5.x. Поточні модулі 2.5.x використовують шаблон Page Controller із системою завантаження mainfile.php. Перегляньте архітектуру XOOPS для поточного життєвого циклу запиту.
:::
Статус
Section titled “Статус”Пропонується - Оцінюється для випуску XOOPS 4.0
Контекст
Section titled “Контекст”Поточний підхід
Section titled “Поточний підхід”XOOPS 2.5 використовує монолітний підхід обробки запитів:
// Current: Sequential processingrequire_once 'mainfile.php';// → Kernel initialization// → User authentication// → Module loading// → Page rendering
// All in one flow, mixed concernsПроблеми з поточним підходом
Section titled “Проблеми з поточним підходом”- Змішані проблеми – автентифікація, журналювання, маршрутизація – все взаємопов’язане
- Важко перевірити – Важко піддати модульному тесту окремі етапи обробки запиту
- Важко розширити - модулі можуть підключитися лише через preload/events
- Погане розділення – логіка обробки запитів розкидана по кодовій базі
- Не можна складати – неможливо легко об’єднати або змінити порядок кроків обробки
Що таке проміжне програмне забезпечення PSR-15?
Section titled “Що таке проміжне програмне забезпечення PSR-15?”PSR-15 defines a standard interface for HTTP middleware:
<?phpinterface RequestHandlerInterface { public function handle(ServerRequestInterface $request): ResponseInterface;}
interface MiddlewareInterface { public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface;}Мережа проміжного програмного забезпечення:
Request ↓[Logger] → logs request ↓[Auth] → validates user session ↓[CORS] → checks cross-origin ↓[Router] → dispatches to handler ↓[Handler] → generates response ↓ResponseРішення
Section titled “Рішення”Прийняти стек проміжного програмного забезпечення PSR-15 для XOOPS 4.0
Section titled “Прийняти стек проміжного програмного забезпечення PSR-15 для XOOPS 4.0”Впровадити конвеєр обробки запитів на основі проміжного ПЗ відповідно до стандарту PSR-15.
Огляд архітектури
Section titled “Огляд архітектури”graph TD subgraph "Request Processing Pipeline" A["HTTP Request<br/>(PSR-7 ServerRequest)"] B["Middleware Stack<br/>(PSR-15)"] C["Logger Middleware"] D["Session Middleware"] E["Auth Middleware"] F["CORS Middleware"] G["Router Middleware"] H["Handler<br/>(Controller/Action)"] I["Response<br/>(PSR-7 Response)"] end
A --> B B --> C C --> D D --> E E --> F F --> G G --> H H --> IОсновні компоненти проміжного програмного забезпечення
Section titled “Основні компоненти проміжного програмного забезпечення”1. Проміжне ПЗ (основний рівень)
Section titled “1. Проміжне ПЗ (основний рівень)”<?phpdeclare(strict_types=1);
namespace XoopsCore;
use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;use Psr\Http\Server\MiddlewareInterface;use Psr\Http\Server\RequestHandlerInterface;
class SessionMiddleware implements MiddlewareInterface{ public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface { // 1. Retrieve session (or start new) $sessionId = $request->getCookieParams()['PHPSESSID'] ?? null; $session = $this->sessionManager->load($sessionId);
// 2. Attach session to request $request = $request->withAttribute('session', $session);
// 3. Pass to next middleware $response = $handler->handle($request);
// 4. Set session cookie if needed if ($session->isModified()) { $response = $response->withAddedHeader( 'Set-Cookie', 'PHPSESSID=' . $session->getId() . '; HttpOnly; SameSite=Strict' ); }
return $response; }}2. Проміжне програмне забезпечення автентифікації
Section titled “2. Проміжне програмне забезпечення автентифікації”<?phpclass AuthMiddleware implements MiddlewareInterface{ public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface { // Get session from previous middleware $session = $request->getAttribute('session');
// Authenticate user from session $user = $this->authenticate($session);
// Attach user to request $request = $request->withAttribute('user', $user);
return $handler->handle($request); }
private function authenticate(?Session $session): User { if ($session && $session->has('uid')) { return $this->userRepository->findById($session->get('uid')); }
return new AnonymousUser(); }}3. Проміжне програмне забезпечення авторизації
Section titled “3. Проміжне програмне забезпечення авторизації”<?phpclass AuthorizationMiddleware implements MiddlewareInterface{ public function __construct(private AuthorizationChecker $checker) { }
public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface { $user = $request->getAttribute('user'); $route = $request->getAttribute('route');
// Check if user has permission for this route if (!$this->checker->isGranted($user, $route)) { return new JsonResponse( ['error' => 'Unauthorized'], 403 ); }
return $handler->handle($request); }}4. Проміжне програмне забезпечення модуля
Section titled “4. Проміжне програмне забезпечення модуля”<?php// Modules can provide their own middlewareclass PublisherAccessMiddleware implements MiddlewareInterface{ public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface { $user = $request->getAttribute('user');
// Module-specific access control if (!$user->hasPermission('publisher_view')) { return new HtmlResponse('Access denied', 403); }
return $handler->handle($request); }}Приклад реалізації
Section titled “Приклад реалізації”<?php// bootstrap.php - Application setup
use Psr\Http\Message\ServerRequestInterface;use Psr\Http\Server\RequestHandlerInterface;use Xoops\Core\Middleware\{ LoggerMiddleware, SessionMiddleware, AuthMiddleware, CorsMiddleware, ErrorHandlingMiddleware};
// Create middleware pipeline$middlewareStack = [ // 1. Error handling (outermost) new ErrorHandlingMiddleware(),
// 2. Logging new LoggerMiddleware($logger),
// 3. CORS handling new CorsMiddleware($corsConfig),
// 4. Session management new SessionMiddleware($sessionManager),
// 5. Authentication new AuthMiddleware($userRepository),
// 6. Authorization new AuthorizationMiddleware($authChecker),
// 7. Routing and dispatching new RoutingMiddleware($router),
// 8. Module middleware (dynamic) ...$this->loadModuleMiddleware(),];
// Process request through middleware stack$request = ServerRequestFactory::fromGlobals();$dispatcher = new MiddlewareDispatcher($middlewareStack);$response = $dispatcher->dispatch($request);
// Send responsehttp_response_code($response->getStatusCode());foreach ($response->getHeaders() as $name => $values) { foreach ($values as $value) { header("$name: $value", false); }}echo $response->getBody();Інтеграція модуля
Section titled “Інтеграція модуля”Модулі можуть надавати проміжне ПЗ:
<?php// Publisher module - xoops_version.php
$modversion['middleware'] = [ 'PublisherAccessMiddleware' => true, // Auto-load 'PublisherLogMiddleware' => true,];
// Or custom:$modversion['middleware_factory'] = function() { return [ new PublisherCacheMiddleware(), new PublisherPermissionMiddleware(), ];};Наслідки
Section titled “Наслідки”Позитивні ефекти
Section titled “Позитивні ефекти”- Поділ завдань - кожне проміжне програмне забезпечення несе одну відповідальність
- Можливість до тестування – легке модульне тестування окремих компонентів проміжного програмного забезпечення
- Компонування - проміжне програмне забезпечення можна змішувати та змінювати порядок
- Сумісність зі стандартами - використовує стандарти PSR-15 і PSR-7
- Розширюваність - Модулі можуть легко додавати спеціальне проміжне програмне забезпечення
- Налагодження - очищення потоку запитів через конвеєр
- Продуктивність - може оптимізувати певні рівні проміжного програмного забезпечення
- Сумісність - можна використовувати стороннє проміжне програмне забезпечення PSR-15
Негативні ефекти
Section titled “Негативні ефекти”- Крива навчання - розробники повинні розуміти PSR-15
- Накладні витрати на продуктивність - більше викликів функцій у конвеєрі
- Складність – більше рухомих частин, ніж монолітний підхід
- Зусилля з міграції - вимагає рефакторингу існуючого коду
- Залежності – потрібна бібліотека HTTP PSR-7
Ризики та пом’якшення
Section titled “Ризики та пом’якшення”| Ризик | Тяжкість | Пом’якшення |
|---|---|---|
| Складні ланцюжки проміжного програмного забезпечення | Середній | Чітка документація, приклади |
| Зниження продуктивності | Середній | Тест, оптимізація гарячих шляхів |
| Зловживання розробником | Середній | Огляд коду, посібник із найкращих практик |
| Зміни порушення міграції | Високий | Термін амортизації, помічники |
| Питання замовлення проміжного ПЗ | Середній | Очистити графік залежностей |
План реалізації
Section titled “План реалізації”Фаза 1: Основа (Q2 2026)
Section titled “Фаза 1: Основа (Q2 2026)”- Реалізація оболонки HTTP-повідомлення PSR-7
- Створити MiddlewareDispatcher
- Реалізація основного проміжного програмного забезпечення (сеанс, авторизація)
- Оновити ядро для використання проміжного ПЗ
Фаза 2: Інтеграція (Q3 2026)
Section titled “Фаза 2: Інтеграція (Q3 2026)”- Перенесення наявних функцій на проміжне ПЗ
- Додати підтримку проміжного програмного забезпечення модуля
- Створення утиліт тестування проміжного ПЗ
- Напишіть вичерпну документацію
Етап 3: міграція (Q4 2026)
Section titled “Етап 3: міграція (Q4 2026)”- Надати рівень сумісності для старого коду
- Довідкові модулі оновлюються до нового проміжного ПЗ
- Оптимізація продуктивності
- Аудит безпеки
Фаза 4: Випуск (Q1 2027)
Section titled “Фаза 4: Випуск (Q1 2027)”- [] XOOPS 4.0 випуск із проміжним програмним забезпеченням
- Застаріла система preload/hook
- Відгуки та оновлення спільноти
Критерії успіху
Section titled “Критерії успіху”- Усі основні функції перенесено на проміжне програмне забезпечення
- 90%+ тестове покриття для проміжного ПЗ
- Документація з прикладами
- Продуктивність на 10% від попередньої версії
- Модулі успішно використовують нову систему проміжного програмного забезпечення
- Рівень прийняття спільнотою >80%
Практичні поради проміжного програмного забезпечення
Section titled “Практичні поради проміжного програмного забезпечення”- Зберігайте фокус на проміжному програмному забезпеченні (одна відповідальність)
- Використовуйте незмінність (створіть новий request/response)
- Витончено поводьтеся з помилками
- Залежності документів
- Додайте підказки щодо типу
- Написати тести для проміжного ПЗ
- Використовуйте стандартні інтерфейси PSR-15
Не треба
Section titled “Не треба”- Не змінюйте спільні об’єкти request/response
- Не звертайтеся безпосередньо до глобалів
- Не створюйте залежності від порядку проміжного ПЗ
- Не ловіть усі винятки
- Не змішуйте бізнес-логіку з проміжним програмним забезпеченням
- Не змушуйте проміжне ПЗ робити занадто багато
Приклади
Section titled “Приклади”Спеціальне проміжне програмне забезпечення
Section titled “Спеціальне проміжне програмне забезпечення”<?php// Example: Rate limiting middleware
use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;use Psr\Http\Server\MiddlewareInterface;use Psr\Http\Server\RequestHandlerInterface;
class RateLimitMiddleware implements MiddlewareInterface{ public function __construct( private RateLimiter $limiter, private int $limit = 100, private int $window = 3600 ) { }
public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface { $user = $request->getAttribute('user'); $identifier = $user->getId() ?? $request->getClientIp();
// Check rate limit $remaining = $this->limiter->check($identifier, $this->limit, $this->window);
if ($remaining < 0) { return new JsonResponse( ['error' => 'Rate limit exceeded'], 429 ); }
// Add rate limit headers $response = $handler->handle($request); return $response ->withAddedHeader('X-RateLimit-Limit', (string)$this->limit) ->withAddedHeader('X-RateLimit-Remaining', (string)$remaining); }}Пов’язані рішення
Section titled “Пов’язані рішення”- ADR-001: Модульна архітектура - основа
- ADR-004: система безпеки - використовує проміжне програмне забезпечення для авторизації
- ADR-006: двофакторна авторизація - може бути проміжним програмним забезпеченням
Посилання
Section titled “Посилання”Стандарти PSR
Section titled “Стандарти PSR”Фреймворки проміжного програмного забезпечення
Section titled “Фреймворки проміжного програмного забезпечення”- [Slim Framework] (https://www.slimframework.com/) - Приклади проміжного ПЗ
- [Zend Expressive] (https://docs.zendframework.com/zend-expressive/) - фреймворк PSR-15
- Guzzle - проміжне програмне забезпечення клієнта HTTP
Інструменти
Section titled “Інструменти”- RelayPHP - Бібліотека проміжного програмного забезпечення
- [PSR-15 Middleware] (https://github.com/middlewares) - Колекція проміжного програмного забезпечення
Історія версій
Section titled “Історія версій”| Версія | Дата | Зміни |
|---|---|---|
| 1.0.0 | 2024-01-28 | Початкова пропозиція |
#xoops #adr #psr-15 #middleware #architecture #psr-7