🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 控制器 ## 基础控制器 ### 生成控制器 ``` // 普通控制器,默认继承基础类 $ php artisan make:controller PhotoController // 生成单个行为控制器 $ php artisan make:controller ShowProfile --invokable // 生成资源控制器 $ php artisan make:controller PhotoController --resource // 指定资源模型,生成时可选是否创建模型,控制器方法注入指定的模型 $ php artisan make:controller PhotoController --resource --model=Photo // 生成API资源路由 $ php artisan make:controller Api/PhotoController --api ``` ### 定义控制器 ``` <?php namespace App\Http\Controllers; use App\User; use App\Http\Controllers\Controller; class UserController extends Controller { /** * 显示给定用户的概要文件. * * @param int $id * @return View */ public function show($id) { return view('user.profile', ['user' => User::findOrFail($id)]); } } ``` >[success] 注意:控制器并不是强制要求继承基础类 。 但是如果没有继承基础类,将无法使用一些便捷的功能,比如 middleware, validate 和 dispatch 方法。 ### 定义控制器路由 在路由文件定义路由,只需要指定命名空间为`App\Http\Controllers`之后的部分 ``` // 定义路由 Route::get('user/{id}', 'UserController@show'); // 完整的控制器类名为 App\Http\Controllers\Photos\AdminController Route::get('foo', 'Photos\AdminController@method'); ``` ### 单个行为控制器 ``` <?php namespace App\Http\Controllers; use App\User; use App\Http\Controllers\Controller; class ShowProfile extends Controller { /** * 展示给定用户的资料. * * @param int $id * @return View */ public function __invoke($id) { return view('user.profile', ['user' => User::findOrFail($id)]); } } // 路由定义,无需指明方法 Route::get('user/{id}', 'ShowProfile'); // 生成单个行为控制器 $ php artisan make:controller ShowProfile --invokable ``` ## 控制器中间件 ``` // 中间件可以在路由文件中分配给控制器的路由或路由组 Route::get('profile', 'UserController@show')->middleware('auth'); // 在控制器中指定中间件,使用更灵活 class UserController extends Controller { /** * Instantiate a new controller instance. * * @return void */ public function __construct() { $this->middleware('auth'); $this->middleware('log')->only('index'); // 只适用 index 方法 $this->middleware('subscribed')->except('store'); // 排除 store 方法,其他都适用 } } // 在控制器中闭包注册中间件 ,不需要注册中间件,方便单个控制器使用 public function __construct() { $this->middleware(function ($request, $next) { // ... return $next($request); }); } ``` >[success] 提示:你可以将中间件分配给控制器操作的一个子集;但是,它可能表明你的控制器正在变得很大。建议你将控制器拆分为多个较小的控制器。 ## 资源控制器 ``` // 生成资源控制器 $ php artisan make:controller PhotoController --resource // 指定资源模型,是否创建模型,控制器方法注入指定的模型 $ php artisan make:controller PhotoController --resource --model=Photo // 定义路由 Route::resource('photos', 'PhotoController'); // 定义多个资源控制器 Route::resources([ 'photos' => 'PhotoController', 'posts' => 'PostController' ]); ``` **资源路由请求方法** HTTP 方法 | URI | 动作 | 路由名称 ----------|-----------------------|--------------|--------------------- GET | `/photos` | index | photos.index GET | `/photos/create` | create | photos.create POST | `/photos` | store | photos.store GET | `/photos/{photo}` | show | photos.show GET | `/photos/{photo}/edit` | edit | photos.edit PUT/PATCH | `/photos/{photo}` | update | photos.update DELETE | `/photos/{photo}` | destroy | photos.destroy **表单方法伪造** ``` // PUT、PATCH、DELETE <form action="/foo/bar" method="POST"> <input type="hidden" name="_method" value="PUT"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> </form> <form action="/foo/bar" method="POST"> @method('PUT') @csrf </form> ``` ### 部分资源路由 ``` // 指定控制器需要处理的部分行为 Route::resource('photos', 'PhotoController')->only([ 'index', 'show' ]); Route::resource('photos', 'PhotoController')->except([ 'create', 'store', 'update', 'destroy' ]); ``` ### API资源路由 >[success] 排除 create 和 edit 显示 HTML 模板的路由 ``` // 生成API资源路由 $ php artisan make:controller Api/PhotoController --api Route::apiResource('photos', 'PhotoController'); Route::apiResources([ 'photos' => 'PhotoController', 'posts' => 'PostController' ]); ``` ### 重命名路由方法 ``` Route::resource('photos', 'PhotoController')->names([ 'create' => 'photos.build' ]); // 设置所有资源路由的前缀 Route::resource('photos', 'PhotoController', ['names' => 'admin.photos']); ``` ### 重命名路由参数 ``` // 生成路由uri为 /users/{admin_user} Route::resource('users', 'AdminUserController')->parameters([ 'users' => 'admin_user' ]); ``` ### 全局重命名路由方法 ``` // 在 AppServiceProvider 的 boot 方法中使用 Route::resourceVerbs 方法实现 use Illuminate\Support\Facades\Route; /** * 初始化任何应用服务 * * @return void */ public function boot() { Route::resourceVerbs([ 'create' => 'crear', 'edit' => 'editar', ]); } // 生成路由uri /fotos/crear /fotos/{foto}/editar ``` ### 定义默认方法以外的路由 >[success] 为资源控制器添加默认路由之外的额外路由,需要在 Route::resource 之前定义 ``` Route::get('photos/popular', 'PhotoController@method'); Route::resource('photos', 'PhotoController'); ``` ## 依赖注入 & 控制器 ### 构造函数注入 ``` <?php namespace App\Http\Controllers; use App\Repositories\UserRepository; class UserController extends Controller { /** * The user repository instance. */ protected $users; /** * Create a new controller instance. * * @param UserRepository $users * @return void */ public function __construct(UserRepository $users) { $this->users = $users; } } ``` ### 方法注入 ``` <?php namespace App\Http\Controllers; use Illuminate\Http\Request; class UserController extends Controller { /** * Store a new user. * * @param Request $request * @return Response */ public function store(Request $request, $id) { $name = $request->name; // } } ``` >[success] 路由参数放在这些依赖项的后面