Создание CommonController в laravel

Большинство моих контроллеров в laravel выглядят одинаково

Пример:

class CourseController extends Controller
{
    public function index(Request $request)
    {
        $courses = Course::query();
        $courses = $this->commonIndex($courses, $request);
        return CourseResource::collection($courses);
    }
    public function store(StoreCourseRequest $request)
    {
        $course = Course::create($request->validated);
        return CourseResource::make($course);
    }
    public function show(Request $request, Course $course)
    {
        return CourseResource::make($course);
    }
    public function update(UpdateCourseRequest $request, Course $course)
    {
        $course->update($request->validated());
        return CourseResource::make($course);
    }
    public function destroy(Course $course)
    {
        $course->delete();
        return response()->noContent();
    }
}

Я хотел бы создать общий контроллер, который расширяется всеми простыми контроллерами и передает Model, FormRequest и Resource как общедоступные переменные, примерно так.

class CommonController extends BaseController
{
    use AuthorizesRequests, ValidatesRequests;
    public $model;
    public $resource;
    public $storeFormRequest;
    public $updateFormRequest;
    public function index(Request $request)
    {
        $model = new $this->model;
        $resource = new $this->resource($request);
        $data = $model->query();
        return $resource->collection($data);
    }
    public function show(Request $request, string $id)
    {
        $model = new $this->model;
        $resource = new $this->resource($request);
        $data = $model->find($id);
        return $resource->make($data->load($loadWith));
    }
    public function store(Request $request)
    {
        $model = new $this->model;
        $resource = new $this->resource($request);
        $request = new $this->storeFormRequest($request->toArray());
        $validated = $request->validated();
        $data = $model->create($validated);
        return $resource->make($data);

    }
}

Я не знаю, как лучше всего передать общедоступные переменные конструктору и оценить их.

Также я столкнулся с проблемой, когда new $this->storeFormRequest($request->toArray()) оценивается как ноль.

$storeFormRequest — это стандартный Laravel FormRequest

class StoreCourseRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'name' => 'required|string',
            'description' => 'required|string',
            'language_id' => 'required|exists:languages,id',
            'image' => 'array',
        ];
    }
}

Вот как я использую CommonController

class CourseController extends CommonController
{
    public $model = Course::class;
    public $resource = CourseResource::class;
    public $storeFormRequest = StoreCourseRequest::class;
    public $updateFormRequest = StoreCourseRequest::class;
}

Вы написали use CommonController; значит это должно быть чертой характера? или вы хотите это как класс ??

Mohammad si abbou 02.07.2024 10:44

@Mohammadsiabbou извините за то, что я использовал черту под названием CommonController, которая отличается от контроллера, я удалил ее из своего вопроса

K i 02.07.2024 10:47

Я бы порекомендовал сделать базовый класс абстрактным с помощью сеттеров, для второго вопроса $request->toArray(), можете ли вы отладить больше и предоставить более подробную информацию об этом.

Mohammad si abbou 02.07.2024 10:52
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
3
80
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

В целом, если ваша реализация контроллера базового класса работает так, как вы хотите, следуйте правилу «если он не сломан, не чините его»;)

Было сказано, что...

Я не знаю, как лучше всего передать общедоступные переменные конструктору и оценить их.

Поскольку вам не требуется доступ к переменным-членам извне класса, вы можете их создать protected; нет необходимости в функциях «установщика».

class CommonController extends BaseController
{
    use AuthorizesRequests, ValidatesRequests;

    protected $model;
    protected $resource;
    protected $storeFormRequest;
    protected $updateFormRequest;

    ...
}

class CourseController extends CommonController
{
    protected $model = Course::class;
    protected $resource = CourseResource::class;
    protected $storeFormRequest = StoreCourseRequest::class;
    protected $updateFormRequest = StoreCourseRequest::class;
}

Вы можете немного привести в порядок методы CommonController, используя статические методы там, где они доступны.

Например, вместо этого:

    $model = new $this->model;
    ...
    $data = $model->find($id);    

сделай это:

    $data = ($this->model)::find($id);

Если бы это был я, я бы сделал следующее: Сначала я бы определил CommonController как абстрактный класс, а затем добавил четыре абстрактных метода для получения соответствующего имени класса обработки.

abstract protected function GetModel(): string;
abstract protected function GetResource(): string;
abstract protected function GetStoreFormRequest(): string;
abstract protected function GetUpdateFormRequest(): string;

Затем я реализую в подклассе четыре метода для возврата имени класса.

protected function GetModel(): string
{
    return Course::class;
}

Почему? Использование абстрактных методов ограничивает возможность их реализации каждым подклассом. Это всего лишь мое личное мнение, я не думаю, что на этот вопрос есть правильный ответ.

Другие вопросы по теме