Controllery a odpovede
Čo ponúka `AbstractController` a kedy sa oplatí pridať spoločnú aplikačnú vrstvu.
Základ frameworku: AbstractController
Framework poskytuje AbstractController s helpermi pre requesty, response a služby, napríklad view(), url(), validator(), flash(), filesystem(), upload(), translator() a breadcrumb().
<?php
declare(strict_types=1);
namespace App\Controllers;
use Lemonade\Framework\Core\AbstractController;
use Psr\Http\Message\ResponseInterface;
final class ArticleController extends AbstractController
{
public function detail(int $id): ResponseInterface
{
return $this->json([
'id' => $id,
'expects_json' => $this->expectsJson(),
]);
}
}Spoločný aplikačný controller
Aplikácia môže voliteľne pridať AppController extends AbstractController. Hodí sa na spoločné renderovanie, zdieľané dáta, metadata, breadcrumbs alebo drobné helpery. Nie je to požiadavka frameworku.
<?php
declare(strict_types=1);
namespace App\Controllers;
use Lemonade\Framework\Core\AbstractController;
use Psr\Http\Message\ResponseInterface;
abstract class AppController extends AbstractController
{
/**
* @param array<string, mixed> $data
*/
protected function page(string $view, array $data = [], int $status = 200): ResponseInterface
{
return $this->html(
$this->view()->template(
'layouts.app',
$view,
$data,
),
$status,
);
}
}Ďalšie vrstvy vo väčších aplikáciách
Vo väčšej aplikácii môžeš nad AppController pridať ďalšie vrstvy pre verejný web, administráciu, prácu s locale alebo canonical redirecty. Je to rozhodnutie aplikácie, nie povinná hierarchia frameworku.
AbstractController
↓
Optional application base controller
↓
Optional specialized controller
↓
Concrete controllerPoužiť môžeš aj čistý PSR controller
Controller nemusí dediť z AbstractController, ak ti viac vyhovuje skladať PSR response priamo cez ResponseFactoryInterface a StreamFactoryInterface.
<?php
declare(strict_types=1);
namespace App\Controllers;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamFactoryInterface;
final class StatusController
{
public function __construct(
private readonly ResponseFactoryInterface $responses,
private readonly StreamFactoryInterface $streams,
) {}
public function index(): ResponseInterface
{
return $this->responses
->createResponse(200)
->withHeader('Content-Type', 'text/html; charset=UTF-8')
->withBody($this->streams->createStream('<h1>Status OK</h1>'));
}
}