前言:
最近在学习 laravel 框架,学习的版本是 7.15.0 ,记录一下学习过程中遇到的问题和难点以及一些总结。
控制器入门
定义控制器
使用 Artisan 命令快速创建一个控制器:
php artisan make:controller UsersController //创建一个名为Users的控制器
UsersController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Http\Request;
class UsersController extends BaseController
{
/**
* @param int $id
* @return Response|\Illuminate\Http\JsonResponse
* @author LaravelAcademy.org
*/
public function show(Request $request)
{
$param = $request -> all();
return response() -> json(['code' => 1, 'data' => $param]);
}
}
routes/api.php 中定义路由
Route::post('user', 'UsersController@show');
命名空间
命名空间定义 App\Http\Controllers 是因为 RouteServiceProvider 将会在一个指定了控制器所在命名空间的路由分组中载入路由文件。
protected $namespace = 'App\Http\Controllers';
在 App\Http\Controllers 目录下选择使用 PHP 命名空间嵌套或组织控制器,只需要使用相对于 App\Http\Controllers 命名空间的指定类名即可。因此,如果你的完整控制器类是 App\Http\Controllers\Photos\AdminController,则可以像这样注册路由:
Route::get('method', 'Photos\AdminController@method');
单一动作控制器
想要定义一个只处理一个动作的控制器,可以在这个控制器中定义 __invoke 方法,通过以下 Artisan 命令快速创建单一动作控制器,只需带上 --invokable 选项即可:
php artisan make:controller ShowProfile --invokable
运行以后会生成 ShowProfile.php 的控制器文件
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class ShowProfile extends Controller
{
/**
* Handle the incoming request.
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
*/
public function __invoke(Request $request)
{
$param = $request -> all();
return response() -> json(['code' => 1, 'data' => $param]);
}
}
单动作控制器注册路由的时候,不需要指定方法:
Route::get('user', 'ShowProfile');
控制器中间件
在 app/Http/Kernel.php 中的指定路由中间件部分 $routeMiddleware 中添加
'token' => \App\Http\Middleware\CheckToken::class,//分配验证token的中间件
中间件 app/Http/Middleware/CheckToken.php
<?php
namespace App\Http\Middleware;
use Closure;
class CheckToken
{
/**
* Handle an incoming request.
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$token = $request->header('token');
if (empty($token) || $token == 'null') {
return response()->json('账号信息过期,请重新登录!', 401);
}
return $next($request);
}
}
之后中间件可以像这样分配给控制器路由:
Route::get('profile', 'UserController@show')->middleware('token');
在控制器的构造函数中使用 middleware 方法你可以很轻松地分配中间件给该控制器(该方法继承自控制器基类),这样该中间件对所有控制器方法都生效:
<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Http\Request;
class UsersController extends BaseController
{
public function __construct()
{
$this->middleware('token');
}
/**
* @param int $id
* @return Response|\Illuminate\Http\JsonResponse
* @author LaravelAcademy.org
*/
public function show(Request $request)
{
$param = $request -> all();
return response() -> json(['code' => 1, 'data' => $param]);
}
}
这样在调取接口的时候需要在 header 头中添加 token 参数,不然 token 验证不过去。
$this->middleware('token')->only('show'); // 只对show方法生效
$this->middleware('token')->except('show'); // 对该show法以外的方法生效
$this->middleware('token')->only(['show', 'index']); // 只对指定show、index方法生效
$this->middleware('token')->except(['show', 'index']); // 对指定show、index方法以外的方法生效
另外在控制器中还可以使用闭包注册中间件:
$this->middleware(function ($request, $next) {
// ...
return $next($request);
});
<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class UsersController extends BaseController
{
public function __construct()
{
$this->middleware('token');
// $this->middleware('token')->except('show'); // 只对该方法生效
//这里使用了闭包注册中间件,在调用方法 show 的时候需要再多传个参数 key,不然会出现抛出的 404 错误
$this->middleware(function ($request, $next) {
if(!is_numeric($request->input('key'))) {
return response()->json('缺少参数key,请重试!', 401);
}
return $next($request);
});
}
/**
* @param int $id
* @return Response|\Illuminate\Http\JsonResponse
* @author LaravelAcademy.org
*/
public function show(Request $request)
{
$param = $request -> all();
return response() -> json(['code' => 1, 'data' => $param]);
}
}