路由 & 控制器

    控制器文件默认在 usr/Controller文件夹内。

    支持的(请求)方法:

    ?> 路由配置修改后需要重启(restart)或者重新加载(reload)服务。

    路由处理器可以是一个匿名函数

    1. $route->get('/hello/{name}', function (\Cabal\Core\Http\Server $server, \Psr\Http\Message\ServerRequestInterface $request, $vars = []) {
    2. return "hello " . $vars['name'];
    3. });
    1. function hello (\Cabal\Core\Http\Server $server, \Psr\Http\Message\ServerRequestInterface $request, $vars = []) {
    2. return "hello " . $vars['name'];
    3. }
    4. $route->get('/hello/{name}', 'hello');

    也可以是一个类中的方法,可以是动态方法也可以是静态方法

    文件 usr/Controller/HelloController.php 内容如下:

    1. namespace Controller;
    2. use Psr\Http\Message\ServerRequestInterface;
    3. use Cabal\Core\Http\Server;
    4. class HelloController
    5. {
    6. function getWorld(Server $server, ServerRequestInterface $request, $vars = [])
    7. {
    8. return "hello " . $vars['name'];
    9. }
    10. static public function staticWorld(Server $server, ServerRequestInterface $request, $vars = [])
    11. {
    12. return "hello " . $vars['id'];
    13. }
    14. }

    增加路由配置:

    ?> 路径规则支持正则等配置,具体可以查看 fastRoute文档

    路由组

    1. $route->group([
    2. 'namespace' => 'Controller',
    3. 'basePath' => '/group',
    4. ], function ($route) {
    5. $route->get('/hello2[/{name}]', 'HelloController@getWorld');
    6. $route->get('/hello3/{id:\d+}', 'HelloController::staticWorld');
    7. });

    或者

    1. $route->group([
    2. 'basePath' => '/group',
    3. $route->get('/hello2[/{name}]', 'HelloController@getWorld');
    4. $route->get('/hello3/{id:\d+}', 'HelloController::staticWorld');
    5. })->namespace('Controller');
    • 为使用中间件时传入的参数.
    • $next($server, $request, $vars); 为下一个中间件或者控制器,要中断请不要调用它。
    1. // 在 routes.php 文件内 定义中间件
    2. $dispatcher->addMiddleware('before', function (\Cabal\Core\Http\Server $server, \Psr\Http\Message\ServerRequestInterface $request, $vars, $next, $middlewareArgs = []) {
    3. // code..
    4. return "before " . $middlewareArgs['name']; // 直接返回,不执行控制器代码,会继续执行其他中间件
    5. });
    6. $dispatcher->addMiddleware('after', function (\Cabal\Core\Http\Server $server, \Psr\Http\Message\ServerRequestInterface $request, $vars, $next, $middlewareArgs = []) {
    7. $response = $next($server, $request, $vars); // 先调用控制器
    8. // code..
    9. return "after: " . $response; // 返回,如果还有其他中间件会继续执行其他中间件
    10. });
    11. // 使用中间件
    12. $route->group([
    13. 'basePath' => '/group',
    14. 'namespace' => 'Controller',
    15. ], function ($route) {
    16. $route->get('/hello2[/{name}]', 'HelloController@getWorld');
    17. $route->get('/hello3/{id:\d+}', 'HelloController::staticWorld');
    18. })->middleware(['after']);
    19. $route->get('/hello2[/{name}]', 'Controller\\HelloController@getWorld')
    20. ->middleware(['before' => ['name' => 'middleware']]);
    21. $route->get('/hello3/{id:\d+}', 'Controller\\HelloController::staticWorld')
    22. ->middleware(['before' => ['name' => 'middleware']]);

    域名&协议

    路由支持按协议或者域名过滤请求。

    控制器继承 Cabal\Core\Base\FilterController 并实现 rules 方法,返回对应方法的规则即可自动约束请求参数。

    !> 校验只会校验请求参数,路由匹配出来的参数($vars)不参与校验!

    我们使用的校验类为:,支持的配置项和语法请参考该项目文档。

    1. <?php
    2. namespace App\Controller;
    3. use Cabal\Core\Http\Request;
    4. use Cabal\Core\Base\FilterController;
    5. class UserController extends FilterController
    6. {
    7. {
    8. 'get' => [
    9. 'id' => ['required', 'integer'],
    10. 'email' => ['required', 'email', ['lengthMin', 4]],
    11. ],
    12. ];
    13. }
    14. public function get(\Server $server, Request $request, $vars = [])
    15. {
    16. return [
    17. 'action' => __METHOD__,
    18. 'input' => $request->all(),
    19. 'vars' => $vars,
    20. ];
    21. }
    22. }

    请求参数没通过校验系统会抛出一个Cabal\Core\Exception\BadRequestException异常,你可以在routes.php中自定义异常处理来决定你的请求响应。

    1. use Cabal\Core\Exception\BadRequestException;
    2. $dispatcher->registerExceptionHandler(function ($server, $ex, $chain, $request) {
    3. if ($ex instanceof BadRequestException) {
    4. return [
    5. 'code' => 1,
    6. 'msg' => $ex->getMessage(),
    7. 'msgs' => $ex->getMessages(),
    8. ];
    9. }
    10. return [
    11. 'code' => -1,
    12. 'msg' => 'Internal Server Error',
    13. ];
    14. });

    代码提示

    1. /**
    2. * @var \Cabal\Core\Dispatcher $dispatcher
    3. */
    4. /**