我正在修改我在项目中使用的CMS,最近我决定为默认操作创建一个控制器 BaseController
,所有其他控制器将扩展此控制器 BaseController
。
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
class BaseController extends Controller
{
protected $viewFolder = 'admin';
protected $title;
protected $model;
protected $key = 'id';
protected $files = [];
public function __construct()
{
$this->setVariable('title', $this->title);
}
public function index()
{
$items = $this->model::paginate();
$this->setVariable('items', $items);
return $this->viewRender('index');
}
public function create()
{
return $this->viewRender('create');
}
public function store(ExampleStoreRequestFROMEXAMPLECONTROLLER $request)
{
$item = $this->model::create($request->all());
return redirect()->route($this->viewFolder.'.'.$this->viewType.'.show', $item[$this->key]);
}
public function show($id)
{
$item = $this->model::where($this->key, $id)->firstOrFail();
$this->setVariable('item', $item);
return $this->viewRender('show');
}
public function edit($id)
{
$item = $this->model::where($this->key, $id)->firstOrFail();
$this->setVariable('item', $item);
return $this->viewRender('edit');
}
public function update(ExampleUpdateRequestFROMEXAMPLECONTROLLER $request, $id)
{
$item = $this->model::where($this->key, $id)->firstOrFail();
$item->update($request->except(['_token', '_method']));
return redirect()->route($this->viewFolder.'.'.$this->viewType.'.show', $item[$this->key]);
}
public function status(ExampleStatusRequestFROMEXAMPLECONTROLLER $request, $id)
{
$this->model::where($this->key, $id)->update($request->except('_method'));
return response()->json([
'message' => 'O status foi alterado com sucesso'
]);
}
public function destroy($id)
{
$this->model::where($this->key, $id)->delete();
return redirect()->route($this->viewFolder.'.'.$this->viewType.'.index');
}
}
问题是:我写了 BaseController
使用表格请求 UserController
我不知道如何保留这些请求动态,以便我可以从其他控制器实现它们。
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Requests\ExampleStatusRequest;
use App\Http\Requests\ExampleStoreRequest;
use App\Http\Requests\ExampleUpdateRequest;
class ExampleController extends BaseController
{
protected $viewType = 'users';
protected $model = 'App\Example';
public function index()
{
$this->setVariable('title', 'Usuários');
return parent::index();
}
public function create()
{
$this->setVariable('title', 'Cadastrar usuário');
return parent::create();
}
public function store(ExampleStoreRequest $request)
{
return parent::store($request);
}
public function edit($id)
{
$this->setVariable('title', 'Editar usuário');
return parent::edit($id);
}
public function update(ExampleUpdateRequest $request, $id)
{
return parent::update($request, $id);
}
public function status(ExampleStatusRequest $request, $id)
{
return parent::status($request, $id);
}
}
这是我的默认控制器:
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
protected $viewFolder = '';
protected $viewType = '';
protected $viewVariables = [];
protected function setVariable($key, $value)
{
$this->viewVariables[$key] = $value;
}
protected function viewRender($view)
{
return view($this->viewFolder.'.pages.'.$this->viewType.'.'.$view, $this->viewVariables);
}
}
知道怎么解决这个问题吗?
评论之后,我可以更好地理解。
我在这里遇到了同样的问题,这是我的解决方法
class BaseController extends Controller
{
protected function _store($request)
{
....
}
...
}
class MyController extends BaseController
{
....
public function store(MyRequest $request)
{
//do something
return parent::_store($request);
}
}
任何 CustomFormRequest
您将使用的,将是一个实例 FormRequest
..一个反过来扩展的类 Request
类。所以在你的 BaseController
做这个:
BaseController.php
use Illuminate\Http\Request;
// some code
public function store(Request $request)
{
$item = $this->model::create($request->all());
return redirect()
->route($this->viewFolder.'.'.$this->viewType.'.show', item[$this->key]);
}
// The rest of your code..
然后在你的孩子控制器:
AChildController.php
class AChildController extends BaseController
{
use App\Http\Requests\ACustomFormRequest;
// Some code
public function store(ACustomFormRequest $request)
{
//do something
return parent::_store($request);
}
}
试一试。
class BaseController extends Controller
{
protected function _store($request)
{
....
}
...
}
class MyController extends BaseController
{
....
public function store(MyRequest $request)
{
//do something
return parent::_store($request);
}
}
简短回答:
绑定。
一 Route::model
。
一个 简单的绑定 对于每个表单请求类型,使用接口 控制器中的方法注入。
长答案适用于您的示例:
模型绑定 routes/web.php
:
<?php
Route::model('example', App\Example::class);
Route::resource('example', 'Admin\ExampleController');
请求Controller Base中的绑定:
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class BaseController extends Controller
{
// Your code...
/**
* @var string[]|callable[]
*/
protected $bindings = [];
/**
* Controller constructor.
*/
public function __construct()
{
$this->addBindings();
}
/**
* Add controller specific bindings.
*/
protected function addBindings()
{
$app = Container::getInstance();
foreach ($this->getBindings() as $abstract => $concrete) {
$app->bind($abstract, $concrete);
}
}
// Your code...
public function store(Requests\StoreRequestInterface $request)
{
// Your code...
}
public function show(Model $item)
{
// Your code...
}
public function edit(Model $item)
{
// Your code...
}
public function update(Requests\UpdateRequestInterface $request, Model $model)
{
// Your code...
}
public function status(Requests\StatusRequestInterface $request, Model $model)
{
// Your code...
}
public function destroy(Model $item)
{
// Your code...
}
// Your code...
}
和示例控制器:
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Requests;
class ExampleController extends BaseController
{
// Your code...
/**
* @var string[]|callable[]
*/
protected $bindings = [
Requests\StatusRequestInterface::class => Requests\ExampleStatusRequest::class,
Requests\StoreRequestInterface::class => Requests\ExampleStoreRequest::class,
Requests\UpdateRequestInterface::class => Requests\ExampleUpdateRequest::class,
];
// Your code...
}
所以Requests接口看起来像这样:
<?php
namespace App\Http\Requests;
interface StoreRequestInterface
{
}
您应该将它用作表单请求中的接口:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ExampleStoreRequest extends FormRequest implements StoreRequestInterface
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return false;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
}
意见的替代答案:
一般控制器基础:
<?php
namespace App\Http\Controllers;
use Illuminate\Container\Container;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
abstract class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
/**
* The view subdirectory that must be used.
*
* @var string
*/
protected $viewDir;
/**
* Bindings
*
* @var string[]|callable[]
*/
protected $bindings = [];
/**
* Controller constructor.
*/
public function __construct()
{
$this->addViewPath();
$this->addBindings();
$this->init();
}
/**
* @return void
*/
protected function init()
{
//
}
/**
* @return string
*/
protected function getViewDir()
{
return $this->viewDir;
}
/**
* @return callable[]|string[]
*/
protected function getBindings()
{
return $this->bindings;
}
/**
* Add controller specific view path.
*/
protected function addViewPath()
{
if (null !== ($dir = $this->getViewDir()) && ($path = realpath(base_path('resources/views/' . $dir)))) {
view()->getFinder()->addLocation($path);
}
}
/**
* Add controller specific bindings.
*/
protected function addBindings()
{
$app = Container::getInstance();
foreach ($this->getBindings() as $abstract => $concrete) {
$app->bind($abstract, $concrete);
}
}
}
资源控制器基础:
<?php
namespace App\Http\Controllers;
use Illuminate\Database\Eloquent\Model;
use App\Http\Requests\StoreRequestInterface;
use App\Http\Requests\UpdateRequestInterface;
use App\Http\Requests\StatusRequestInterface;
abstract class ResourceController extends Controller
{
/**
* Model class
*
* @var string
*/
protected $modelClass;
/**
* @var string
*/
protected $viewDirPrefix;
/**
* @return string
*/
protected function getViewDir()
{
return $this->viewDir ?:
ltrim($this->viewDirPrefix . DIRECTORY_SEPARATOR . 'pages', DIRECTORY_SEPARATOR) .
DIRECTORY_SEPARATOR . strtolower(class_basename($this->modelClass));
}
/**
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function getQuery()
{
return call_user_func($this->modelClass . '::query');
}
/**
* @return string
*/
protected function getName()
{
return __(class_basename($this->modelClass));
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
protected function index()
{
$title = __('resource.title.index', ['name' => str_plural($this->getName())]);
$models = $this->getQuery()->paginate();
return view('index', compact('title', 'models'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
protected function create()
{
$title = __('resource.title.create', ['name' => $this->getName()]);
return view('create', compact('title'));
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request|StoreRequestInterface $request
*
* @return \Illuminate\Http\Response
*/
public function store(StoreRequestInterface $request)
{
$model = $this->getQuery()->create($request->all());
return redirect()
->route(substr($request->route()->getName(), 0, -5) . 'show', $model);
}
/**
* Display the specified resource.
*
* @param \Illuminate\Database\Eloquent\Model $model
*
* @return \Illuminate\Http\Response
*/
public function show(Model $model)
{
$title = __('resource.title.show', ['name' => $this->getName()]);
return view('show', compact('title', 'model'));
}
/**
* Show the form for editing the specified resource.
*
* @param \Illuminate\Database\Eloquent\Model $model
*
* @return \Illuminate\Http\Response
*/
public function edit(Model $model)
{
$title = __('resource.title.edit', ['name' => $this->getName()]);
return view('edit', compact('title', 'model'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request|UpdateRequestInterface $request
* @param \Illuminate\Database\Eloquent\Model $model
*
* @return \Illuminate\Http\Response
*/
public function update(UpdateRequestInterface $request, Model $model)
{
$model->update($request->except(['_token', '_method']));
return redirect()
->route(substr($request->route()->getName(), 0, -6) . 'show', $model);
}
/**
* Remove the specified resource from storage.
*
* @param \Illuminate\Database\Eloquent\Model $model
*
* @return \Illuminate\Http\Response
* @throws \Exception
*/
public function destroy(Model $model)
{
$model->delete();
return redirect()
->route(substr(request()->route()->getName(), 0, -7) . 'index');
}
/**
* @param \Illuminate\Http\Request|StatusRequestInterface $request
* @param \Illuminate\Database\Eloquent\Model $model
*
* @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse
*/
protected function status(StatusRequestInterface $request, Model $model)
{
$model->update($request->except('_method'));
return response()->json([
'message' => __('resource.status.success'),
]);
}
}
资源控制器 Example
模型:
<?php
namespace App\Http\Controllers\Admin;
use App\Example;
use App\Http\Requests;
use App\Http\Controllers\ResourceController;
class ExampleController extends ResourceController
{
/**
* Model class
*
* @var string
*/
protected $modelClass = Example::class;
/**
* @var string
*/
protected $viewDirPrefix = 'admin';
/**
* @var string[]|callable[]
*/
protected $bindings = [
Requests\StatusRequestInterface::class => Requests\Example\StatusRequest::class,
Requests\StoreRequestInterface::class => Requests\Example\StoreRequest::class,
Requests\UpdateRequestInterface::class => Requests\Example\UpdateRequest::class,
];
}
英语语言文件 resources/lang/en/resource.php
:
<?php
return [
'title' => [
'index' => 'All :Name',
'create' => 'Create :Name',
'show' => 'Show :Name',
'edit' => 'Edit :Name',
],
'status' => [
'success' => 'Status updated successfully',
],
];
葡萄牙语语言文件 resources/lang/pt/resource.php
:
<?php
return [
'title' => [
'index' => 'Todos os :Name',
'create' => 'Cadastrar :Name',
'show' => 'Show :Name',
'edit' => 'Editar :Name',
],
'status' => [
'success' => 'O status foi alterado com sucesso',
],
];
网络路线 routes/web.php
:
<?php
Route::group([
'as' => 'admin.',
'prefix' => 'admin',
'namespace' => 'Admin',
], function () {
Route::model('example', App\Example::class);
Route::resource('example', 'ExampleController');
});
请求接口(用于绑定):
<?php
namespace App\Http\Requests;
interface StoreRequestInterface
{
}
同样的 App\Http\Requests\UpdateRequestInterface
和 App\Http\Requests\StatusRequestInterface
...
示例表单请求:
<?php
namespace App\Http\Requests\Example;
use Illuminate\Foundation\Http\FormRequest;
use App\Http\Requests\StoreRequestInterface;
class StoreRequest extends FormRequest implements StoreRequestInterface
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return false;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
}
同样的 App\Http\Requests\Example\UpdateRequest
和 App\Http\Requests\Example\StatusRequest
...
适用于此回复的文档:
注意: 本回复适用于Laravel 5.6。预览版本不支持此回复中使用的某些代码。如果您想要特定版本,请告诉我,我会尝试对其进行调整。