ADR-005 - Corak Pertengahan PSR-15
ADR-005: Corak Pertengahan PSR-15 untuk XOOPS 4.0> Gunakan pengendali permintaan pelayan PSR-15 HTTP (perisian tengah) untuk saluran paip pemprosesan permintaan yang lebih baik.:::awas[XOOPS 4.0 Cadangan — Tidak Tersedia dalam 2.5.x]
Section titled “ADR-005: Corak Pertengahan PSR-15 untuk XOOPS 4.0> Gunakan pengendali permintaan pelayan PSR-15 HTTP (perisian tengah) untuk saluran paip pemprosesan permintaan yang lebih baik.:::awas[XOOPS 4.0 Cadangan — Tidak Tersedia dalam 2.5.x]”ADR ini menerangkan seni bina yang dicadangkan untuk XOOPS 4.0. Perisian tengah PSR-15 tidak tersedia dalam XOOPS 2.5.x. Modul 2.5.x semasa menggunakan corak Pengawal Halaman dengan tali but mainfile.php. Lihat XOOPS Architecture untuk kitaran hayat permintaan semasa.
:::---
StatusDicadangkan - Dalam penilaian untuk keluaran XOOPS 4.0---
Section titled “StatusDicadangkan - Dalam penilaian untuk keluaran XOOPS 4.0---”Konteks### Pendekatan SemasaXOOPS 2.5 menggunakan pendekatan pengendalian permintaan monolitik:
Section titled “Konteks### Pendekatan SemasaXOOPS 2.5 menggunakan pendekatan pengendalian permintaan monolitik:”php// Current: Sequential processingrequire_once 'mainfile.php';// → Kernel initialization// → User authentication// → Module loading// → Page rendering
// All in one flow, mixed concernsMasalah dengan Pendekatan Semasa1. Kebimbangan Campuran - Pengesahan, pengelogan, penghalaan semuanya saling berkaitan
Section titled “Masalah dengan Pendekatan Semasa1. Kebimbangan Campuran - Pengesahan, pengelogan, penghalaan semuanya saling berkaitan”- Sukar untuk Diuji - Sukar untuk menguji unit langkah pemprosesan permintaan individu
- Sukar untuk Dipanjangkan - Modul hanya boleh menyambung melalui preload/events
- Pemisahan Lemah - Permintaan logik pemprosesan yang tersebar di seluruh pangkalan kod
- Tidak Boleh Gubah - Tidak dapat merantai atau menyusun semula langkah pemprosesan dengan mudah### Apakah itu PSR-15 Middleware?PSR-15 mentakrifkan antara muka standard untuk perisian tengah HTTP:
php<?phpinterface RequestHandlerInterface { public function handle(ServerRequestInterface $request): ResponseInterface;}
interface MiddlewareInterface { public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface;}Rantai Peranti Tengah:
Request ↓[Logger] → logs request ↓[Auth] → validates user session ↓[CORS] → checks cross-origin ↓[Router] → dispatches to handler ↓[Handler] → generates response ↓ResponseKeputusan### Gunakan Timbunan Perisian Tengah PSR-15 untuk XOOPS 4.0Laksanakan saluran pemprosesan permintaan berasaskan middleware mengikut piawaian PSR-15.### Gambaran Keseluruhan Seni Bina
Section titled “Keputusan### Gunakan Timbunan Perisian Tengah PSR-15 untuk XOOPS 4.0Laksanakan saluran pemprosesan permintaan berasaskan middleware mengikut piawaian PSR-15.### Gambaran Keseluruhan Seni Bina”mermaidgraph 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 --> IKomponen Perisian Tengah Teras#### 1. Perisian Tengah Aplikasi (Lapisan Teras)
Section titled “Komponen Perisian Tengah Teras#### 1. Perisian Tengah Aplikasi (Lapisan Teras)”php<?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. Perisian Tengah Pengesahan
Section titled “2. Perisian Tengah Pengesahan”php<?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. Perisian Tengah Kebenaran
Section titled “3. Perisian Tengah Kebenaran”php<?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. Modul Middleware
Section titled “4. Modul Middleware”php<?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); }}Contoh Pelaksanaan
Section titled “Contoh Pelaksanaan”php<?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();Integrasi ModulModul boleh menyediakan perisian tengah:
Section titled “Integrasi ModulModul boleh menyediakan perisian tengah:”php<?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(), ];};Akibat### Kesan Positif1. Pengasingan Kebimbangan - Setiap perisian tengah mengendalikan satu tanggungjawab
Section titled “Akibat### Kesan Positif1. Pengasingan Kebimbangan - Setiap perisian tengah mengendalikan satu tanggungjawab”- Kebolehujian - Mudah untuk unit menguji komponen middleware individu
- Composability - Middleware boleh dicampur dan disusun semula
- Patuh Piawaian - Menggunakan piawaian PSR-15 dan PSR-7
- Kebolehlanjutan - Modul boleh menambah perisian tengah tersuai dengan mudah
- Nyahpepijat - Kosongkan aliran permintaan melalui saluran paip
- Prestasi - Boleh mengoptimumkan lapisan middleware tertentu
- Saling kendali - Boleh menggunakan perisian tengah PSR-15 pihak ketiga### Kesan Negatif1. Keluk Pembelajaran - Pembangun mesti memahami PSR-15
- ** Overhed Prestasi** - Lebih banyak panggilan fungsi dalam talian paip
- Kerumitan - Lebih banyak bahagian yang bergerak daripada pendekatan monolitik
- Usaha Migrasi - Memerlukan pemfaktoran semula kod sedia ada
- Pergantungan - Memerlukan perpustakaan PSR-7 HTTP### Risiko dan Tebatan| Risiko | Keterukan | Mitigasi | |------|----------|-----------| | Rangkaian perisian tengah yang kompleks | Sederhana | Dokumentasi yang jelas, contoh | | Kemerosotan prestasi | Sederhana | Penanda aras, optimumkan laluan panas | | Penyalahgunaan pembangun | Sederhana | Semakan kod, panduan amalan terbaik | | Perubahan pecah migrasi | Tinggi | Tempoh penamatan, pembantu | | Isu pesanan middleware | Sederhana | Kosongkan graf pergantungan |---
Rancangan Pelaksanaan### Fasa 1: Asas (S2 2026)- [ ] Laksanakan pembalut mesej PSR-7 HTTP
Section titled “Rancangan Pelaksanaan### Fasa 1: Asas (S2 2026)- [ ] Laksanakan pembalut mesej PSR-7 HTTP”- Cipta MiddlewareDispatcher
- Laksanakan perisian tengah teras (sesi, pengesahan)
- Kemas kini kernel untuk menggunakan perisian tengah### Fasa 2: Penyepaduan (S3 2026)- [ ] Pindahkan fungsi sedia ada kepada perisian tengah
- Tambah sokongan perisian tengah modul
- Buat utiliti ujian middleware
- Tulis dokumentasi yang komprehensif### Fasa 3: Migrasi (S4 2026)- [ ] Sediakan lapisan keserasian untuk kod lama
- Modul bantuan mengemas kini kepada perisian tengah baharu
- Pengoptimuman prestasi
- Audit keselamatan### Fasa 4: Keluaran (S1 2027)- [ ] Keluaran XOOPS 4.0 dengan perisian tengah
- Hentikan sistem preload/hook lama
- Maklum balas dan kemas kini komuniti---
Kriteria Kejayaan- [ ] Semua fungsi teras dipindahkan ke perisian tengah
Section titled “Kriteria Kejayaan- [ ] Semua fungsi teras dipindahkan ke perisian tengah”- liputan ujian 90%+ untuk perisian tengah
- Documentation complete with examples
- Prestasi dalam 10% daripada versi sebelumnya
- Modul berjaya menggunakan sistem middleware baharu
- Kadar penggunaan komuniti >80%---
Amalan Terbaik Middleware### Lakukan- Pastikan perisian tengah fokus (tanggungjawab tunggal)
Section titled “Amalan Terbaik Middleware### Lakukan- Pastikan perisian tengah fokus (tanggungjawab tunggal)”- Gunakan kebolehubahan (buat request/response) baharu
- Tangani ralat dengan anggun
- Kebergantungan dokumen
- Tambah petunjuk jenis
- Tulis ujian untuk perisian tengah
- Gunakan antara muka PSR-15 standard### Jangan- Jangan ubah suai objek request/response kongsi
- Jangan akses global secara langsung
- Don’t create dependencies on middleware order
- Jangan tangkap semua pengecualian
- Jangan campurkan logik perniagaan dengan middleware
- Jangan buat middleware melakukan terlalu banyak---
Contoh### Perisian Tengah Tersuai
Section titled “Contoh### Perisian Tengah Tersuai”php<?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); }}Keputusan Berkaitan- ADR-001: Seni Bina Modular - Asas
Section titled “Keputusan Berkaitan- ADR-001: Seni Bina Modular - Asas”- ADR-004: Sistem Keselamatan - Menggunakan perisian tengah untuk pengesahan
- ADR-006: Pengesahan Dua Faktor - Boleh menjadi perisian tengah---
Rujukan### Piawaian PSR- PSR-7: HTTP Antara Muka Mesej
Section titled “Rujukan### Piawaian PSR- PSR-7: HTTP Antara Muka Mesej”- PSR-15: Pengendali Permintaan Pelayan HTTP### Rangka Kerja Middleware- Rangka Kerja Slim - Contoh perisian tengah
- Zend Expressive - Rangka kerja PSR-15
- Guzzle - HTTP perisian tengah pelanggan### Alat- RelayPHP - Pustaka middleware
- PSR-15 Middleware - Koleksi middleware---
Sejarah Versi| Versi | Tarikh | Perubahan |
Section titled “Sejarah Versi| Versi | Tarikh | Perubahan |”|---------|------|---------| | 1.0.0 | 28-01-2024 | Cadangan awal |---
#XOOPS #adr #psr-15 #middleware #architecture #psr-7