您当前的位置: 首页 > 慢生活 > 程序人生 网站首页程序人生
webman-路由-路由中间件
发布时间:2022-01-19 22:36:50编辑:雪饮阅读()
路由配置于config/route.php:
给单个某个路由设置中间件,中间件可以有一个或多个
实例:
路由配置:
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
use Webman\Route;
Route::any('/Foo/{id}', [app\controller\Foo::class, 'index'])->middleware([
app\middleware\ActionHook::class,
app\middleware\ActionHook2::class,
]);
被加入路由的控制器:
\app\controller\Foo.php:
<?php
namespace app\controller;
use support\Request;
class Foo
{
/**
* 该方法会在请求前调用
*/
public function beforeAction(Request $request)
{
echo 'beforeAction';
// 若果想终止执行Action就直接返回Response对象,不想终止则无需return
// return response('终止执行Action');
}
/**
* 该方法会在请求后调用
*/
public function afterAction(Request $request, $response)
{
echo 'afterAction';
// 如果想串改请求结果,可以直接返回一个新的Response对象
// return response('afterAction');
}
public function index(Request $request,$id)
{
return response('hello index id:'.$id);
}
}
config/middleware/ActionHook.php中间件配置:这里配置的是全局中间件,路由中间件用的中间件列表中若某个路由中间件存在于这里则该中间件会被重复调用
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [];
中间件\app\middleware\ActionHook.php的实现:为了调试方便,在中间件中为响应体追加内容,就可以在请求时候看到该中间件被调用
<?php
namespace app\middleware;
use support\Container;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
class ActionHook implements MiddlewareInterface
{
public function process(Request $request, callable $next) : Response
{
if ($request->controller) {
// 禁止直接访问beforeAction afterAction
if ($request->action === 'beforeAction' || $request->action === 'afterAction') {
return response('<h1>404 Not Found</h1>', 404);
}
$controller = Container::get($request->controller);
if (method_exists($controller, 'beforeAction')) {
$before_response = call_user_func([$controller, 'beforeAction'], $request);
if ($before_response instanceof Response) {
return $before_response;
}
}
$response = $next($request);
if (method_exists($controller, 'afterAction')) {
$after_response = call_user_func([$controller, 'afterAction'], $request, $response);
if ($after_response instanceof Response) {
return $after_response;
}
}
$body=$response->rawBody();
$body.=" ActionHook ";
$response->withBody($body);
return $response;
}
return $next($request);
}
}
config/middleware/ActionHook2.php中间件配置:与上面中间件同理
<?php
namespace app\middleware;
use support\Container;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
class ActionHook2 implements MiddlewareInterface
{
public function process(Request $request, callable $next) : Response
{
if ($request->controller) {
// 禁止直接访问beforeAction afterAction
if ($request->action === 'beforeAction' || $request->action === 'afterAction') {
return response('<h1>404 Not Found</h1>', 404);
}
$controller = Container::get($request->controller);
if (method_exists($controller, 'beforeAction')) {
$before_response = call_user_func([$controller, 'beforeAction'], $request);
if ($before_response instanceof Response) {
return $before_response;
}
}
$response = $next($request);
if (method_exists($controller, 'afterAction')) {
$after_response = call_user_func([$controller, 'afterAction'], $request, $response);
if ($after_response instanceof Response) {
return $after_response;
}
}
$body=$response->rawBody();
$body.=" ActionHook2";
$response->withBody($body);
return $response;
}
return $next($request);
}
}
被请求时:
[root@localhost ~]# elinks http://127.0.0.1:8787/Foo/1 --dump
hello index id:1 ActionHook2 ActionHook
可以看到路由中间件列表中中间件应用顺序遵循先进后出顺序。
路由中间件对分组路由的支持
config/route.php重新配置为;
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
use Webman\Route;
Route::group('/blog', function () {
Route::any('/create', function () {
return response('blog create');
});
Route::any('/edit', function () {
return response('blog edit');
});
Route::any('/view/{id}', function ($r, $id) {
return response("blog view $id");
});
Route::any('/create2', [app\controller\Foo::class, 'index2']);
Route::any('/edit2', [app\controller\Foo::class, 'edit2']);
Route::any('/view2/{id}', [app\controller\Foo::class, 'view2']);
})->middleware([
app\middleware\ActionHook::class,
app\middleware\ActionHook2::class,
]);
控制器\app\controller\Foo.php新增点方法:
<?php
namespace app\controller;
use support\Request;
class Foo
{
/**
* 该方法会在请求前调用
*/
public function beforeAction(Request $request)
{
echo 'beforeAction';
// 若果想终止执行Action就直接返回Response对象,不想终止则无需return
// return response('终止执行Action');
}
/**
* 该方法会在请求后调用
*/
public function afterAction(Request $request, $response)
{
echo 'afterAction';
// 如果想串改请求结果,可以直接返回一个新的Response对象
// return response('afterAction');
}
public function index(Request $request,$id)
{
return response('hello index id:'.$id);
}
public function index2(Request $request)
{
return response('foo index2');
}
public function edit2(Request $request)
{
return response('foo edit2');
}
public function view2(Request $request)
{
return response('foo view2');
}
}
再次请求时:
[root@localhost ~]# elinks http://127.0.0.1:8787/blog/create --dump
blog create
[root@localhost ~]# elinks http://127.0.0.1:8787/blog/edit --dump
blog edit
[root@localhost ~]# elinks http://127.0.0.1:8787/blog/view/1 --dump
blog view 1
[root@localhost ~]# elinks http://127.0.0.1:8787/blog/create2 --dump
foo index2 ActionHook2 ActionHook
[root@localhost ~]# elinks http://127.0.0.1:8787/blog/edit2 --dump
foo edit2 ActionHook2 ActionHook
[root@localhost ~]# elinks http://127.0.0.1:8787/blog/view2/1 --dump
foo view2 ActionHook2 ActionHook
可以看到仅对分组路由中有类路由起到了中间件的作用,对于无类(匿名路由)无效,具体应该是涉及到中间件的实现了。
关键字词:webman,路由,中间件