dc/router

HTTP 路由器

0.1.3 2014-11-20 08:20 UTC

This package is not auto-updated.

Last update: 2024-09-14 15:58:07 UTC


README

DC\Router - Easy HTTP routing

安装

$ composer install dc/router

或者将其添加到 composer.json

"require": {
	"dc/router": "0.*",
    "dc/ioc": "0.*"
}
$ composer install

此包建议使用 dc/ioc,但这是一个非常强烈的推荐。没有它使用会很痛苦。

Build status

入门

我们强烈建议您使用 dc/ioc,我们在所有示例中都使用它以方便设置。这使得设置变得容易

<?php
$container = new \DC\IoC\Container();

$container->registerModules([
    new \DC\Router\IoC\Module(['\Fully\Qualified\ControllerName', '\CatsController']),
    new \DC\Cache\Module(),
    new \DC\JSON\IoC\Module()
]);

$router = $container->resolve('\DC\Router\Router');
$router->route($container->resolve('\DC\Router\IRequest'));

DC\Router 是基于路由和控制器构建的。路由是一个在 URL 被访问时调用的单个函数。控制器是一个包含一个或多个路由的类,如果其 URL 匹配,则可以调用。以下是一个示例

class CatsController extends \DC\Router\ControllerBase {
	/**
	 * @route GET /cats
	 */
	function list() {
		return "<h1>many cats here</h1>";
	}
}

魔法般的功能是由于以下两个步骤

  1. 您正在从 ControllerBase 继承,该类为您实现了 IController
  2. 您使用 @route PhpDoc 注释装饰了 list 方法,以指定该路径匹配哪个。

路由

特殊的 @route PHPDoc 注释指定哪些 URL 匹配路由。它们支持变量

/**
 * @route GET /cats/{id:int}
 */ 
function getById($id) {
  // $id will be an int here
}

/**
 * @route GET /cats/{name}
 */
function getByName($name) {
  // $name will be a string (we didn't have to specify string as it is the default)
}

/**
 * @route GET /cats/{catName}/toys/{toyId:int}
 */
function getToy($toyId, $catName) {
  // notice that the variables for the method do not need to be in the same order as in the route,
  // but they need to have the same names
}

/**
 * @route GET /cats/?filter={cats:catFilter}
 */
function filterCats($cats, $filter) {
  // This uses the catFilter parameter type (see below) to convert the input sent through the 
  // filter GET parameter and provides it with the variable named $cats. The ONLY time you'll 
  // use this, is if you want parameter type conversion, or when you want to rename the query 
  // parameter before it arrives. Note that the $filter parameter is still available, but is 
  // a string 
}

参数类型

您可以注册自己的参数类型。通过简单地实现 IParameterType,您可以将输入参数从 URL 转换为完整的对象

class CatParameterType implements \DC\Router\IParameterType {
  private $catService;  
  function __construct(\ICatService $catService) {
    $this->catService = $catService;
  }
  function getType() { return "cat"; }
  function getRegularExpression() { return "\d+"; }
  function transformValue($id) {
    return $this->catService->get($id);
  }
}

您需要在创建路由系统之前将其注册到您的 IoC 容器中

$container = new \DC\IoC\Container();

$container->registerModules([
    new \DC\Router\IoC\Module(['\CatsController']),
    new \DC\Cache\Module(),
    new \DC\JSON\IoC\Module()
]);

$container->register('\UserParameterType')->to('\DC\Router\IParameterType')->withContainerLifetime();

$router = $container->resolve('\DC\Router\Router');
$router->route($container->resolve('\DC\Router\IRequest'));

现在您可以在自己的路由中使用它

/**
 * @route GET /cat/{catObject:cat}
 */
function getCatById(\Cat $catObject) {
  var_dump($catObject);
} 

依赖注入

如果您使用上述设置,控制器将在实例化时注入,因此您可以轻松地指定依赖项

class CatsController extends \DC\Router\ControllerBase {
  /**
   * @param \ICatToy[] $catToys A list of the toys you have for your cats
   */
  function __construct(\CatService $catsService, array $catToys) {
     // store your catsService and your toys
  }
}

API 控制器

如果您想创建 JSON API,则继承自 \DC\Router\JsonController 而不是。您返回的任何内容都会在发送到客户端之前自动序列化为 JSON。

这些 API 控制器还可以接收已发布的 JSON 数据,前提是正确设置了 Content-Type 标头。要在路由中访问发布的数据,请使用 getRequestBodyAsObject() 方法

class CatsController extends \DC\Router\JsonController {
  /**
   * @route POST /cat
   */
  function new() {
     $cat = $this->getRequestBodyAsObject();
     return $cat;
  }
}