我在 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;
}
总的来说,如果您的基类控制器的实现按照您想要的方式工作,请遵循“如果它没有损坏,就不要修复它”的规则;)
话虽如此...
我不知道将公共变量传递给构造函数并评估它们的最佳方法是什么。
由于您不需要从类外部访问成员变量,因此您可以将它们设置为
protected
;不需要“setter”功能。
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;
}
为什么? 使用抽象方法会限制每个子类实现它们。 这只是我个人的看法,我认为这个问题没有正确答案