控制器
命令行创建控制器
php artisan make:controller ControllerName
上述命令就会在app\Http\Controllers
下创建一个新的控制器类,老规矩,想直接手工创建的,在这里贴一个基础代码:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ControllerName extends Controller
{
//code...
}
这个基础的控制器类继承了Controller
类,该类其实很简单:
<?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;
}
就是把一些常用的类都封装在了内部,方便其他类直接使用,而不用每个控制器类都要调用上述内容。
这里还要再扯到一个文件:app\Http\Providers\RouteServiceProvider.php
文件,这个文件为所有的路由请求匹配的控制器设置了中间件和命名空间:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{
/**
*这个就是所有路由中所有控制器默认调用的命名空间
* @var string
*/
protected $namespace = 'App\Http\Controllers';
/**
* 这个在上一篇博客中介绍过了,设置路由调用的模型和全局有效的正则验证的
* @return void
*/
public function boot()
{
parent::boot();
}
/**
* 调用函数吧,就是调用下面的两个设置函数,具体作用还未知
* @return void
*/
public function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
}
/**
* 大概意思是web.php中设置的路由都会经过Kernel.php中的web中间件组的验证,而具体的验证就要看web中间件组中设置了哪些验证了
* @return void
*/
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
/**
* 跟上面一样,只不过这里是api.php中的路由和api中间件组
* @return void
*/
protected function mapApiRoutes()
{
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
}
Laravel 的增删改查
在tp中,你的增删改查都是你自己定义,然后传到对应的控制器下的方法就行了,但在Laravel中,控制器的一般增删改查操作都有对应默认的函数名,如果你想减少自己的工作量,那就最好使用他的规则来。
首先先看下面这张表格:(假设该路由请求用户数据,为users)
请求类型 | URL请求 | 默认方法 | 功能介绍 | 路由设置 |
---|---|---|---|---|
GET | users/ | index | 获取全部用户数据 | UserController.index |
GET | `users/create | create` | 获取新增用户的页面 | UserController.create |
POST | users/ | store | 保存新增用户页面提交过来的数据 | UserController.store |
GET | users/{id} | show | 获取单一用户数据 | UserController.show |
GET | users/{id}/edit | edit | 获取编辑用户信息的页面 | UserController.edit |
PUT/PATCH | users/{id} | update | 保存编辑用户信息页面提交过来的数据 | UserController.update |
DELETE | users/{id} | delete | 删除一个用户 | UserController.delete |
从上面这个表格中我们可以看出:
- 相同的URL请求,但是请求的方式不一样,都会被Laravel解析成调用控制器的不同方法
- 获取输入页面和保存页面的方法是不一样的
- 各个操作都有默认的方法,最好直接使用这些方法,这样可以使你的代码更加清爽
路由设置
上面的增删改查就需要设置7个路由,这样会使路由文件很复杂,所以Laravel对上面这样形式的路由设置了一个组合:
Route::resource('users','UserController');
# 如果你只想要其中的部分方法的话,那么可以这么设置
Route::resource('users','UserController',['only'=>['index','show']]);
# 有了only,自然也有expect
Route::resource('users','UserController',['except'=>['create','update']]);
这样当你的URL请求是users/create
时,也会匹配到该路由设置下,并自动调用UserController
下的create
方法。这样路由文件就间接很多了。
这里再多说一句,如果你想命令行创建的控制器自动生成上面的增删改查对应的方法,那么就在使用下面的命令:
php artisan make:controller ControllerName2 --resource
# 如果你想顺道连模型也一起生成的话,那么可以这么设置命令
php artisan make:controller ControllerName3 --model=TableName
如果你在相同控制器中有额外的方法,那么最好把路由定义在resource
前面:
Route::get('users/info','UserController@infoUser');
Route::resource('users','UserController');
单方法控制器
前面在路由设置时都会设置控制器以及该控制器下的方法,但是当对一个控制器的所有调用都只有一个方法时,可以使用PHP的一个魔术方法__invoke
,关于这个方法的介绍,我百度到的结果是:
当尝试以调用函数的方式调用一个对象时,该方法会被自动调用
所以我们在设置路由时:
Route::get('users','UserController');
不用设置具体的方法,只需要在该UserController
内部设置__invoke
方法即可。
中间件调用
前面我们讲过在路由中设置中间件,其实在控制器中也可以设置中间件,同样是middleware
方法:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ControllerName extends Controller
{
public function __construct(){
//这样设置的中间件对该控制器下的所有方法有效
$this->middleware('auth');
//这样设置的中间件只对部分方法有效
$this->middleware('log',['only'=>['create','store']]);
//这样设置的中间件除了下面的部分,其他都有效
$this->middleware('subscribed',['expect'=>['update']])
}
}
甚至可以直接在控制器中设置中间件的处理函数:
$this->middleware(function($request,$next){
return $next($request);
});
方法参数设置
Laravel允许你往控制器中的方法中传递任意类型的数据(传入类时注意命名空间)
<?php
namespace App\Http\Controllers;
use App\Repositories\UserRepository;
class UserController extends Controller
{
/**
* The user repository instance.
*/
protected $users;
/**
*
* @param UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
}
不只是构造函数,一般的函数内部也是支持传入需要参数的
路由参数传入
现在假设路由传入参数如下:
Route::get('users/{id}','UserController@show');
那么你可以直接在控制器中传入该参数:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function show(Request $request, $id){
//code...
}
}
路由缓存
有时候你会发现自己刚更新了路由文件没有立刻生效,是因为Laravel会缓存路由设置,这个时候想要立刻生效,就需要人为清除路由缓存:
# 清除路由缓存
php artisan route:clear
# 强制更新缓存
php artisan route:cache