路由:简单讲就是定义URL请求转向某个业务逻辑(一般是控制器方法)的方法。
1、路由定义文件:
/routes/web.php //定义web访问的路由
/routes/api.php //定义api访问的路由,此路由定义的url都要加/api前缀
怎么增加路由文件:
笨方法就直接在/routes/下添加文件后,再在web.php下添加require引用。
优雅的方法:(参考:https://laravel-china.org/articles/4400/laravel54-add-routing-file)
举例:添加一/routes/admin.php文件,作为定义后台管理的路由文件。
修改/app/Providers/RouteServiceProvider.php服务提供者文件:
添加一方法:
/** * 定义管理后台的路由文件 */ protected function mapAdminRoutes() { Route::prefix('admin') //添加admin前缀(可选) ->middleware('web') //使用web组别的中间件(可选) ->namespace($this->namespace . '\admin') //admin的命名空间(可选) ->group(base_path('routes/admin.php')); //引用admin.php文件 }
然后修改map方法,添加一行执行以上方法代码:
public function map() { $this->mapApiRoutes(); $this->mapWebRoutes(); $this->mapAdminRoutes(); //引用管理后台路由文件 }
这样就能方便地在/routes/admin.php文件内定义后台路由了。
2、路由定义:
可定义的路由请求:
Route::get($uri, $callback); Route::post($uri, $callback); Route::put($uri, $callback); Route::patch($uri, $callback); Route::delete($uri, $callback); Route::options($uri, $callback);
响应多个请求:
Route::match(['get', 'post'], '/', function () { //响应第一参数内的请求,第一参数为数组或字串,第二参数为uri }); Route::any('foo', function () { //响应任意HTTp的请求,第一参数为uri });
路由参数:
参数名在{}内,不能包含-符号。带?号表示可选参数。
//uri: http://domain/user/1 Route::get('user/{id}', function ($id) { return 'User '.$id; }); //uri: http://domain/posts/1/comments/1 Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) { // }); //可选参数 Route::get('user/{name?}', function ($name = null) { return $name; });
可定义正则约束参数:
Route::get('user/{id}/{name}', function ($id, $name) { // })->where(['id' => '[0-9]+', 'name' => '[a-z]+']); //全局约束:修改/app/Providers/RouteServiceProvider.php文件的boot方法。这样对所有使用该参数的路由都起约束: public function boot() { Route::pattern('id', '[0-9]+'); //id参数的全局约束 parent::boot(); }
路由命名:
Route::get('user/profile', function () { // })->name('profile'); Route::get('user/profile', 'UserController@showProfile')->name('profile');
命名的好处:可使用命名来生成该链接或重定向等:
// 生成 URL,等效于route('user/profile') $url = route('profile'); // 生成重定向... return redirect()->route('profile'); //带参数的路由 Route::get('user/{id}/profile', function ($id) { // })->name('profile'); $url = route('profile', ['id' => 1]); //检查当前路由是否为某个name定义的: if ($request->route()->named('profile')) { //常用于中间件检测 }
路由组:用于大量路由中共享路由属性,如中间件、命令空间。
Route::middleware(['first', 'second']) //按顺序使用first, second中间件 ->namespace('Admin') //在 "App\Http\Controllers\Admin" 命名空间下的控制器 ->prefix('admin') //匹配包含 "/admin/users" 的 URL ->name('admin.') //添加路由名称前缀 ->group(function () { Route::get('/', function () { // }); Route::get('user/profile', function () { // }); Route::get('users', function () { // 路由分配名称“admin.users”... })->name('users'); });
Route::domain('{account}.myapp.com')->group(function () { Route::get('user/{id}', function ($account, $id) { //子域名路由 }); });
表单方法伪造: HTML 表单中调用定义了 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 = Route::current();
$name = Route::currentRouteName();
$action = Route::currentRouteAction();