我认为控制器Controller就是用来处理业务逻辑的,除此之外,它不应该干涉model、view等的功能范围。
Laravel中的Controller存放于app/Http/Controllers/
目录之下,当然你可以在此目录下继续建立下级目录用来做区分。
你能够看到在app/Http/Controllers/
目录下已经存在了一个名为Controller.php
的文件,这个可以算是一个基础类,里面包含了可能会用到的一些引用,因此在创建新的Controller时,直接继承此基础类是一个很便捷的方式。
所以一个很简单的Controller定义就是如下这种形式:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class CountryController extends Controller
{
}
然后我们让这个Controller变得有用起来,首先给这个Controller增加一个方法:
public function show(){
echo "Hello, world!";
}
然后在routes/web.php中添加一个相对应的路由:
Route::get('/country', 'CountryController@show');
接着通过请求http://ip:port/country
便能够看到它已经运行了。
在默认目录app/Http/Controllers
下的Controller使用的相同的命名空间App\Http\Controller
,为了某种目的我们可能也会使用不同的命名空间,例如以下这种形式:
[root@vm Controllers]# mkdir Admin
[root@vm Controllers]# cd Admin/
[root@vm Admin]# cp ../CountryController.php ProductController.php
建立了更深一层的目录Admin,这样具体的目录就变成了app/Http/Controllers/Admin/
,然后复制了一个CountryController.php到此目录下并重命名为ProductController.php,同时对ProductController.php进行一些修改,以便使它能够正常运行而且能够被确认与CountryController不相同。
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
class ProductController extends Controller
{
public function show(){
echo __METHOD__."Hello, world!";
}
}
修改后,ProductController的命名空间变了,方法show的输出也变了,为了能够调用到它,在routes/web.php中新添加一条路由信息:
Route::get('/product', 'Admin\ProductController@show');
接下来通过http://ip:port/product就可以调用到这个ProductController下的新的show方法,输出如下:
App\Http\Controllers\Admin\ProductController::showHello, world!
路由产生变化的原因在于ProductController的命名空间产生了变化,而默认的Controller路由是已经添加了App\Http\Controller
命名空间的,所以相对的命名空间,我们需要指定的只是App\Http\Controller\
之后的部份。
还有一种只含有一个方法的控制器,这种控制器可以将包含的唯一的方法命名为__invoke
,然后在路由中调用的时候就可以只写Controller名称而不用写方法名,似乎是个没什么实际作用的东西。
在路由中间件一文中,已经介绍了中间件相关的内容,但中间件不仅可以在路由中指定,也可以在控制器内指定,而且在控制器的构造方法中指定中间件更加方便,更可以约束中间件只对控制器中指定的方法生效。
public function __construct(){
$this->middleware('age')->only('show');
}
指定了中间件age,只对控制器内的show方法生效。
也可以在控制器中直接使用闭包的方式创建中间件,这样可以避免创建一个中间件类。
Laravel中的资源控制器是个奇怪的东西,至少我是这样认为的,因为我实在没有找到它在实际应用中的作用。
通过artisan可以很快捷的创建一个资源控制器:
/usr/local/bin/php artisan make:controller PhotoController --resource
创建出的这个资源控制器中,具有最基本的CURD方法。
根据使用方法的不同,会分为构造函数注入和方法注入两种,具体的就是通过在函数参数中声明某些类对象,然后在函数体中直接使用。
如果该函数同时接收路由参数,那就将路由参数放在声明之后。
public function show(Request $request, $age){
$url = $request->url();
echo "param age = $age, url = $url";
}
这样做能够缩减部份代码量,可以在使用时直接调用而不需要再创建类的对象。
按照官方文档的说法,路由缓存对基于控制器的路由能够大幅减少注册所有路由所需要的时间。
含义类似于事先创建一个相应的缓存,从而在使用的时候直接调用缓存即可,因此这个主要用于线上环境,即不经常修改的环境。
创建路由缓存:
php artisan route:cache
清除路由缓存:
php artisan route:clear