Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Классы-действия

Пока обработчики — функции внутри config/routes.php, файл растёт с каждым маршрутом. Обработчик выносят в отдельный класс — действие (action). Один класс отвечает за один маршрут, а в файле маршрутов остаётся одна строка.

Где лежат действия

Действия кладут в папку src/Action/. Команды для создания в Slim нет: создайте папку и файл вручную.

Первое действие

// src/Action/HomeAction.php
namespace App\Action;
 
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
 
final class HomeAction
{
    public function __invoke(Request $request, Response $response): Response
    {
        $response->getBody()->write('Главная страница блога');
 
        return $response;
    }
}

__invoke — особый метод PHP: объект с таким методом можно вызвать как функцию. Аргументы те же, что у функции-обработчика.

Подключение в маршруте

В config/routes.php вместо функции указывают имя класса:

// config/routes.php
use App\Action\HomeAction;
use Slim\App;
 
return function (App $app): void {
    $app->get('/', HomeAction::class)->setName('home');
};

Откройте http://localhost:8080 — страница та же, но код обработчика теперь в своём файле. Slim сам создаёт объект класса, когда приходит запрос.

Действие с параметром адреса

Параметры адреса приходят третьим аргументом, как и в функции:

// src/Action/ShowPostAction.php
namespace App\Action;
 
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
 
final class ShowPostAction
{
    public function __invoke(Request $request, Response $response, array $args): Response
    {
        $response->getBody()->write('Статья №' . (int) $args['id']);
 
        return $response;
    }
}
// config/routes.php
$app->get('/posts/{id:[0-9]+}', ShowPostAction::class)->setName('posts.show');

Адрес /posts/5 выведет «Статья №5». Не забудьте добавить use App\Action\ShowPostAction; в начало файла маршрутов.

Как называть

Имя действия отвечает на вопрос «что делает маршрут»:

МаршрутКласс
GET /postsListPostsAction
GET /posts/{id}ShowPostAction
POST /postsCreatePostAction

Контроллер вместо действий

Если привычнее контроллер — один класс с несколькими методами, — маршрут записывают массивом из имени класса и имени метода:

// config/routes.php
$app->get('/posts', [PostController::class, 'index']);
$app->get('/posts/{id:[0-9]+}', [PostController::class, 'show']);

Методы index и show принимают те же аргументы, что __invoke. В курсе используются действия: каждый класс короткий и получает только то, что нужно его маршруту.

Частая ошибка

Действие, которое само разбирает запрос, выполняет запросы к базе и собирает HTML, превращается в «толстый» класс. Оставляйте в действии три шага: достать данные из запроса, вызвать другой класс, который делает работу, и сформировать ответ. Как передавать такие классы в действие, показано в следующем уроке.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.