Задать вопрос

Как валидировать параметры роута, или как заменить нативный класс Request на свой собственный?

Доброго дня.
У меня есть сущность Аккаунта, к которой могут относиться разные другие сущности. Например, Пост. CRUD для Постов выглядит примерно так:
/accounts/{account}/posts/{post}
Соответственно, я проверяю в коде контроллера, принадлежит ли Пост переданному Аккаунту, или нет. Если нет, генерирую ошибку. Данный код повторяется из метода в метод, и я хочу вынести его в отдельное правило валидации.

Однако есть проблема: Laravel не предоставляет возможности валидировать параметры роутов. На StackOverflow рекомендуют перегружать метод all() объекта Request, что я и сделал, создав свой собственный класс App\Http\Request. Однако после этого отвалился DI-контейнер: он внедряет в методы контроллера мой собственный Request вместо нативного реквеста Лары, но без данных внутри. Собственно, код моего Request и контроллера под спойлером.
Код Request и контроллера
namespace App\Http;

use Illuminate\Http\Request as NativeRequest;

class Request extends NativeRequest
{
    public function all($keys = null)
    {
        $results = parent::all($keys);
        // тут бы еще подмешивал route->parameters

        return $results;
    }
}

Пытаюсь внедрить собственный Request, но он пуст.
use App\Http\Request;

class PostsController extends Controller
{
    public function update(Request $request, int $accountId, int $postId)
    {
        return $request->all(); // пусто, при этом POST есть. все работает, если вернуть нативный реквест
    }
}

Как быть? Вопросов два, в зависимости от реализуемости каждого из них.
1. Каков best way для валидации параметров роута, если очень нужно?
2. Как заменить нативный Illuminate\Http\Request на свой App\Http\Request так, чтобы внедрение данного класса происходило корректно?
  • Вопрос задан
  • 328 просмотров
Подписаться 1 Средний 6 комментариев
Пригласить эксперта
Ответы на вопрос 2
Alex_Wells
@Alex_Wells
PHP/Kotlin
Вот сниппет с моего проекта. Собственно, я обычные реквесты не использую вообще, и вся валидация всегда в FormRequest'е, так что такое мне подходит. Валидировать как обычно - в rules, самыми обычными правилами, только названия параметров должны начинатся с { и заканчиватся на } - это на всякий случай, что бы нечайно не смешать разные параметры.

use Illuminate\Foundation\Http\FormRequest;

abstract class Request extends FormRequest
{
    /**
     * Get data to be validated from the request.
     *
     * @return array
     */
    protected function validationData()
    {
        return $this->all() + $this->routeParameters();
    }

    /**
     * Get route parameters for this request and wrap them into {} each.
     *
     * @return array
     */
    protected function routeParameters()
    {
        return collect($this->route()->parameters)
            ->mapWithKeys(function ($item, $key) {
                return ['{'.$key.'}' => $item];
            })
            ->toArray();
    }
}
Ответ написан
Комментировать
@Tronyx
В файле RouteServiceProvider, добавляем следующее
public function boot() {
		// Кастомные патерны для проверки переменных в имени роута
		// Если не соответствует регулярке - то не будет выполнен запрос к контроллеру
		Route::pattern('slug', SlugRule::$regexp);
		Route::pattern('id', '\d+');
		parent::boot();
	}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы