当前位置: 首页 > 文档资料 > CabalPHP 中文文档 >

控制器

优质
小牛编辑
134浏览
2023-12-01

路由文件默认在 usr/routes.php,你也可以根据自己的情况修改配置文件,指定路由文件路径。

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

路由配置

支持的(请求)方法:

$route->map($method, $path, $handler);  // method 可以是数组 ['GET', 'POST`]
$route->get($path, $handler); 
$route->get($path, $handler); 
$route->post($path, $handler); 
$route->put($path, $handler); 
$route->patch($path, $handler); 
$route->delete($path, $handler); 
$route->head($path, $handler); 
$route->options($path, $handler); 
$route->any($path, $handler);   // GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS

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

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

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

http://localhost:9501/hello/cabal

也可以是一个函数

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

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

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

namespace Controller;

use Psr\Http\Message\ServerRequestInterface;
use Cabal\Core\Http\Server;

class HelloController
{
    function getWorld(Server $server, ServerRequestInterface $request, $vars = [])
    {
        return "hello " . $vars['name'];
    }

    static public function staticWorld(Server $server, ServerRequestInterface $request, $vars = [])
    {
        return "hello " . $vars['id'];
    }
}

增加路由配置:

$route->get('/hello2[/{name}]', 'Controller\\HelloController@getWorld'); 
$route->get('/hello3/{id:\d+}', 'Controller\\HelloController::staticWorld');

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

路由组

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

或者

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

中间件

中间件和其他框架的中间件类似,不做太多描述,下面是简单的应用,多个中间件的情况可以自己实现后看下效果。

  • $middlewareArgs 为使用中间件时传入的参数.
  • $next($server, $request, $vars); 为下一个中间件或者控制器,要中断请不要调用它。
// 在 routes.php 文件内 定义中间件 
$dispatcher->addMiddleware('before', function (\Cabal\Core\Http\Server $server, \Psr\Http\Message\ServerRequestInterface $request, $vars, $next, $middlewareArgs = []) {
    // code..
    return "before " . $middlewareArgs['name']; // 直接返回,不执行控制器代码,会继续执行其他中间件
});

$dispatcher->addMiddleware('after', function (\Cabal\Core\Http\Server $server, \Psr\Http\Message\ServerRequestInterface $request, $vars, $next, $middlewareArgs = []) {
    $response = $next($server, $request, $vars); // 先调用控制器
    // code..
    return "after: " . $response; // 返回,如果还有其他中间件会继续执行其他中间件

});

// 使用中间件
$route->group([
    'basePath' => '/group',
    'namespace' => 'Controller',
], function ($route) {
    $route->get('/hello2[/{name}]', 'HelloController@getWorld');
    $route->get('/hello3/{id:\d+}', 'HelloController::staticWorld');
})->middleware(['after']); 

$route->get('/hello2[/{name}]', 'Controller\\HelloController@getWorld')
    ->middleware(['before' => ['name' => 'middleware']]);
$route->get('/hello3/{id:\d+}', 'Controller\\HelloController::staticWorld')
    ->middleware(['before' => ['name' => 'middleware']]);

域名&协议

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

$route->group([
    'basePath' => '/group',
], function ($route) {
    $route->get('/hello2[/{name}]', 'HelloController@getWorld');
    $route->get('/hello3/{id:\d+}', 'HelloController::staticWorld');
})->host('www.qq.com')
    ->scheme('https'); 

$route->get('/hello3/{id:\d+}', 'HelloController::staticWorld')
    ->host('www.qq.com') 
    ->scheme('https');

过滤控制器/API控制器

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

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

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

<?php
namespace App\Controller;

use Cabal\Core\Http\Request;
use Cabal\Core\Base\FilterController;

class UserController extends FilterController
{
    public function rules()
    {
        return [
            'get' => [
                'id' => ['required', 'integer'],
                'email' => ['required', 'email', ['lengthMin', 4]],
            ],
        ];
    }

    public function get(\Server $server, Request $request, $vars = [])
    {
        return [
            'action' => __METHOD__,
            'input' => $request->all(),
            'vars' => $vars,
        ];
    }
}

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


use Cabal\Core\Exception\BadRequestException;

$dispatcher->registerExceptionHandler(function ($server, $ex, $chain, $request) {
    if ($ex instanceof BadRequestException) {
        return [
            'code' => 1,
            'msg' => $ex->getMessage(),
            'msgs' => $ex->getMessages(),
        ];
    }
    return [
        'code' => -1,
        'msg' => 'Internal Server Error',
    ];
});

代码提示

为了让 routes.php 有代码提示 请保留下面注释:

/**
 * @var \Cabal\Core\Dispatcher $dispatcher
 */
/**
 * @var \Cabal\Route\RouteCollection $route
 */