crodas/dispatcher

分发器生成器

v1.1.1 2016-04-01 13:39 UTC

README

Dispatcher 是一个将 URL 映射到操作的路由库。

安装

您可以使用 composer 进行安装

composer require crodas/dispatcher:"^1.0"

定义路由

路由通过方法或函数的注解来定义。

use Symfony\Component\HttpFoundation\Request;

/** 
 * A single function can have multiple routes.
 * 
 * @Route("/{user}") 
 * @Route("/user/{user}")
 */
function handler(Request $req, $user)
{
  return "Hello {$user}";
}

/**
 *  You can also set default values and use multiple routes
 *
 *  @Route("/foo/{bar}")
 *  @Route("/foo", {bar="index"})
 */
function do_something_with_bar(Request $request, $bar) {
  print "I've got bar=" . $bar;
}

/**
 *  If @Route is define at a class it would behave as a
 *  namespace of prefix for the routes defined at their
 *  methods
 *
 *  @Route("/admin")
 */
class Foobar
{
  /**
   *  This handles POST /admin/login
   *
   *  @Route("/login")
   *  @Method POST
   */
  public function do_login(Request $req)
  {
  }
  
  /**
   *  This handles GET /admin/login
   *
   *  @Route("/login")
   */
  public function login(Request $req)
  {
  }
}

Dispatcher 会遍历文件系统,寻找函数和方法上的 @Route 注解。

如何使用

$router = new Dispatcher\Router;
$router->
  // where our controllers are located
  ->addDirectory(__DIR__ . "/../projects");

// Do the router
$router->doRoute();

默认情况下,它在 生产模式 下运行,并且不会在更改时重建路由。如果您希望以开发模式运行,应该这样做

$router->development();

过滤器

为了简化,Dispatcher 目前不允许您定义正则表达式来验证占位符。相反,它允许您定义验证和修改占位符值的函数。

/**
 * In this URL, the placeholder user have a Filter, that means
 * if the controller is called we can be sure we get a valid
 * user object.
 *
 * @Route("/profile/{user}")
 */
function show_profile(Request $req, $user) {
  return "Hi {$user->name}";
}


/**
 * Validate {user} placeholders
 *
 * Check if the user exists in the database, if it does exists
 * it will return true and the controller will be called.
 *
 * @Filter("user") 
 */
function some_filter(Request $req, $name, $value) {
  $userobj = DB::getUserById($value);
  if ($userobj) {
    /* I'm overriding the placeholder $name for an object of the Database */
    $req->attributes->set($name, $userobj);
    return true;
  }
  return false;
}

过滤器应返回 false,如果 $value 无效,路由器将跳转到下一个规则或抛出 notfound 异常。使用 $name 是因为一个回调可以用作多个过滤器。

昂贵的 Filters 可以使用 @Cache <ttl> 注解进行缓存。缓存机制由实现 FilterCache 接口的类定义在应用程序中。

有效模式

  • /foo/bar
  • /foo/{user}
  • /foo/{user:user1}/{user:user2}:在 Request 对象内部,用户对象将被命名为 user1user2 以避免名称冲突。
  • /foo/{user:u1}-vs-{user:u2}.{ext}:只要变量之间通过常量分隔,我们就可以在单个目录级别内拥有多个变量。