3.控制器
app/Http/Controllers目录下面就是我们用来存放控制器文件的目录了。你当然可以手动创建一个控制器文件,但是Laravel给你提供了一种更加便捷的方式,借助Laravel提供的artisan文件。
温馨提示:
1.以下操作默认你的PHP环境已经添加到PATH中
2.artisan并非只能生成控制器,还能生成模型,中间件等等,具体可以通过php artisan list查看。
我们来新建一个Controller
php artisan make:controller TestController
这样在app/Http/Controllers/下就会出现一个TestController.php的文件。
控制器的名称单词并非需要首字母大写,也不一定需要加Controller,但是为了统一规范,最好跟Laravel默认的命名规范一致。
打开文件,我们发现新的控制器已经继承了Controller,已添加命名空间,并且引入了常用的Request类。惊不惊喜,意不意外,是不是比手动创建一个Controller文件要快的多,当然,如果你想要里面有一些常用的方法,还可以加上参数–resource
php artisan make:controller TestController --resource
这样生成的Controller文件里面就会多了很多方法,例如常用的增删改查。
如果按上述方式生成控制器文件的话,app/Http/Controllers/下会多很多文件,而且具有相同名称的文件就不能同时存在,这样就失去了命名空间存在的价值,因此我们需要把它们分组。
php artisan make:controller Home/TestController
php artisan make:controller Admin/TestController
这样我们就在app/Http/Controllers/Admin和app/Http/Controllers/Home下同时生成了名为TestController.php的文件。具体如何分组,可以根据项目的实际情况而定。
4.路由和控制器相结合
我们在app/Http/Controllers/TestController中新建一个index方法,然后return ‘Hello World’;
Route::get('/', 'TestController@index');
这样一来我们就把路由和控制器结合起来了,再刷新首页,是不是出现了Hello World呀。
其中控制器的部分以@为分界线分为两部分,前一部分是控制器名称,后面的是方法名称。
上面只是一个简单的路由和控制器的应用,在实际项目中,路由和控制器之间的存在这更为复杂的关系,例如命名空间,中间件等等,下面会简单的介绍一些常用的路由和控制器结合的例子。
4.1 命名空间
上面我们说到了,为了方便管理,我们会对控制器进行分组,这样,控制器文件就不会存在在app/Http/Controllers/下,而是它下面的一个子目录。命名空间就跟目录名称有关,我们来对比下
app/Http/Controllers/TestController.php
app/Http/Controllers/Admin/TestController.php
命名空间分别为
namespace App\Http\Controllers;
namespace App\Http\Controllers\Admin;
多了一个\Admin,此时我们应该怎么样组合路由呢,其实也很简单,只需要把Admin和TestController组合起来。
Route::get('admin/test', 'Admiin\TestController@index');//斜线不要搞反方向了
因为App\Http\Controllers在Laravel中是根命名空间,因此我们只需要把它后面的部分跟控制器组合起来即可。如果是单一的路由这样写没问题,但是路由如果多了,是否有更加便捷的书写方式呢?
Route::get('admin/article', 'Admiin\ArticleController@index');
Route::get('admin/category', 'Admiin\CategoryController@index');
Route::get('admin/user', 'Admiin\UserController@index');
4.2分组
这里就用到了Route::group
Route::group(['namespace'=>'Admin','prefix'=>'admin'], function(){
Route::get('article', 'ArticleController@index');
Route::get('category', 'CategoryController@index');
Route::get('user', 'UserController@index');
});
使用分组最大的好处不在于简化代码,而是更加方便的管理。例如后台所有的控制器都需要登录后才能操作,有了分组我们只需要为分组添加一个限制条件即可,这时中间件就派上用场了。
4.3中间件
中间件的生成也很简单,仍然是试用artisan。
php artisan make:middleware AdminAuth
此时在app/Http/Middleware/下便会出现一个AdminAuth.php文件,那么如何使用中间件呢?
方法一:
在路由文件web.php中直接引入该类
use App\Http\Middleware\AdminAuth;
Route::group(['namespace'=>'Admin','prefix'=>'admin', 'middleware'=>AdminAuth::class], function(){
Route::get('article', 'ArticleController@index');
Route::get('category', 'CategoryController@index');
Route::get('user', 'UserController@index');
});
当然如此书写有点不优雅,换个优雅点的。
方法二:
在app/Http/Kernel.php中$routeMiddleware中新增键值
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'admin.auth' => \App\Http\Middleware\AdminAuth::class,
];
然后在路由文件web.php中调用方法如下
Route::group(['namespace'=>'Admin','prefix'=>'admin', 'middleware'=>'admin.auth'], function(){
Route::get('article', 'ArticleController@index');
Route::get('category', 'CategoryController@index');
Route::get('user', 'UserController@index');
});
小插曲:
系统环境:centos6.8
laravel版本:5.5
php版本:7.1
apache:2.4
在以上环境中,app/Http/Controllers/下生成的所有Controller文件,均不能运用于Route中,都会报
Class App\Http\Controllers\TestController does not exist
文件的命名空间没有任何问题的,起初以为app/Http/Controllers/下不能放Controller文件,但是换了Windows之后再测便可以,所以应该不是Laravel的问题,具体什么问题暂未可知。
补充说明:
不止是app/Http/Controllers/下,子目录下,例如app/Http/Controllers/Home也会出现找不到路由的情况,但是偶然间优化了下composer的时候,发现这些控制器又能用了,暂未知原因。
composer dump-autoload
问题已解决:
原来一切还是composer的问题,为了优化自动加载,使用了以下命令
composer dump-autoload -a(--classmap-authoritative)
使用这个命令之后,因为所有新建的控制器都不在classmap中,所以出现了上述情况。
我们只需要再次运行
composer dump-autoload(不带-a参数)
即可,之后新建的所有控制器又可以正常显示了。