路由

    你在可以使用 实例的代理(proxy)方法来定义应用程序路由。Slim 框架提供了最流行的HTTP方法。

    使用 Slim 应用程序的 get() 方法添加一个只处理 GET HTTP 请求的路由。它接收两个参数:

    • 路由模式(带有可选的命名占位符)/The route pattern (with optional named placeholders)
    • 路由回调

    POST 路由

    使用 Slim 应用程序的 post() 方法添加一个只处理 POST HTTP 请求的路由。它接收两个参数:

    • 路由模式(带有可选的命名占位符)/The route pattern (with optional named placeholders)
    • 路由回调
    1. $app = new \Slim\App();
    2. $app->post('/books', function ($request, $response, $args) {
    3. // Create new book
    4. });

    PUT 路由

    使用 Slim 应用程序的 put() 方法添加一个只处理 PUT HTTP 请求的路由。它接收两个参数:

    • 路由模式(带有可选的命名占位符)/The route pattern (with optional named placeholders)
    • 路由回调
    1. $app = new \Slim\App();
    2. $app->put('/books/{id}', function ($request, $response, $args) {
    3. // Update book identified by $args['id']
    4. });

    DELETE 路由

    使用 Slim 应用程序的 delete() 方法添加一个只处理 DELETE HTTP 请求的路由。它接收两个参数:

    • 路由模式(带有可选的命名占位符)/The route pattern (with optional named placeholders)
    • 路由回调
    1. $app = new \Slim\App();
    2. $app->delete('/books/{id}', function ($request, $response, $args) {
    3. // Delete book identified by $args['id']
    4. });

    使用 Slim 应用程序的 options() 方法添加一个只处理 OPTIONS HTTP 请求的路由。它接收两个参数:

    • 路由模式(带有可选的命名占位符)/The route pattern (with optional named placeholders)
    • 路由回调
    1. $app = new \Slim\App();
    2. $app->options('/books/{id}', function ($request, $response, $args) {
    3. // Return response headers
    4. });

    PATCH 路由

    使用 Slim 应用程序的 patch() 方法添加一个只处理 PATCH HTTP 请求的路由。它接收两个参数:

    • 路由模式(带有可选的命名占位符)/The route pattern (with optional named placeholders)
    • 路由回调
    1. $app = new \Slim\App();
    2. $app->patch('/books/{id}', function ($request, $response, $args) {
    3. });

    任意路由

    使用 Slim 应用程序的 any() 方法添加一个可以处理处理所有 HTTP 请求的路由。它接收两个参数:

    • 路由模式(带有可选的命名占位符)/The route pattern (with optional named placeholders)
    • 路由回调
    1. $app = new \Slim\App();
    2. $app->any('/books/[{id}]', function ($request, $response, $args) {
    3. // Apply changes to books or book identified by $args['id'] if specified.
    4. // To check which method is used: $request->getMethod();
    5. });

    记住,第二个参数是一个回调。你需要指定一个类(Class,需要一个 __invoke() 实现方法。)来替换闭包(Closure)。接着,你可以映射到其他位置:

    1. $app->any('/user', 'MyRestfulController');

    自定义路由

    使用 Slim 应用程序的 map() 方法来添加一个可以处理多个 HTTP 请求方法的路由。它接收三个参数:

    • HTTP 方法的数组
    • 路由模式(带有可选的命名占位符)/The route pattern (with optional named placeholders)
    • 路由回调

    路由回调

    上述的每个路由方法都接收一个回调例程作为其最后一个参数。这个参数可以是任意 PHP 调用(callable),并且它默认接受三个参数。

    请求/Request

    第一个参数是一个 Psr\Http\Message\ServerRequestInterface 对象,表示当前的 HTTP 请求。

    第二个参数是一个 Psr\Http\Message\ResponseInterface 对象,表示当前的 HTTP 响应。

    参数数组/Arguments

    第三个参数是一个关联数组,包含包含当前路由的命名占位符。

    有两种方式可以将内容写入 HTTP 响应。第一钟,可以使用 echo() 简单地从路由回调中输出内容。其内容将会呗追加到当前 HTTP 请求对象中。第二种,你可以返回一个 Psr\Http\Message\ResponseInterface 对象。

    闭包绑定/Closure binding

    如果你使用一个闭包(Closure)实例作为路由回调,闭包的状态受Container实例约束。这意味着你将通过 $this 关键字访问闭包内部的 DI 容器实例:

    1. $app = new \Slim\App();
    2. $app->get('/hello/{name}', function ($request, $response, $args) {
    3. // Use app HTTP cookie service
    4. $this->get('cookies')->set('name', [
    5. 'name' => $args['name'],
    6. ]);
    7. });

    路由回调签名由路由策略决定。默认地,Slim 寄望路由回调来接收请求、响应和由路由占位符参数组成的数组。这称为请求响应策略(RequestResponse strategy)。然而,你可以通过使用另一个不同策略来改变这种寄望。例如,Slim 提供了一个另类的策略,叫做 RequestResponseArgs ,它接收请求和响应,加上由每一个路由占位符组成的单独参数。这里的例子展示了如何使用这个另类的策列;轻松替代了默认\Slim\Container提供的 foundHandler 依赖:

    1. $c = new \Slim\Container();
    2. $c['foundHandler'] = function() {
    3. return new \Slim\Handlers\Strategies\RequestResponseArgs();
    4. };
    5. $app = new \Slim\App($c);
    6. $app->get('/hello/{name}', function ($request, $response, $name) {
    7. return $response->write($name);
    8. });

    通过实现 \Slim\Interfaces\InvocationStrategyInterface 你可以提供一个你自己的路由策略。

    路由占位符

    上诉的每个路由方法都会收到一个 URL 模式(URL pattern),它将与当前 HTTP 请求的 URI 相匹配。路由模式将使用命名占位符(named placeholder)来动态匹配 HTTP 请求的URI 片段。

    格式

    路由模式占位符起始与一个 {, 然后是占位符名称, 最后以 } 结束。这是一个名为 name 的占位符例子:

    1. $app = new \Slim\App();
    2. $app->get('/hello/{name}', function ($request, $response, $args) {
    3. echo "Hello, " . $args['name'];
    4. });

    可选的分段 / Optional segments

    使一个片段可选,只需用将其放在方括号中:

    1. $app->get('/users[/{id}]', function ($request, $response, $args) {
    2. // reponds to both `/users` and `/users/123`
    3. // but not to `/users/`
    4. });

    支持多个可选参数嵌套:

    1. $app->get('/news[/{year}[/{month}]]', function ($request, $response, $args) {
    2. // reponds to `/news`, `/news/2016` and `/news/2016/03`
    3. });

    对于数目不确定的可选参数,可以这样做:

    1. $app->get('/news[/{params:.*}]', function ($request, $response, $args) {
    2. $params = explode('/', $request->getAttribute('params'));
    3. // $params is an array of all the optional segments
    4. });

    在这个例子中,/news/2016/03/20 的 URI 将使得 $params 数组包含三个元素:['2016', '03', '20'].

    1. $app = new \Slim\App();
    2. $app->get('/users/{id:[0-9]+}', function ($request, $response, $args) {
    3. // Find user identified by $args['id']
    4. });

    应用程序的路由可以被指定一个名称。这非常有用,如果你想要使用路由的 pathFor() 方法以编程的形式生成一个特定路由的 URL 。上述的每个路由方法都会返回一个 \Slim\Route 对象,这个对象带来了 setName() 方法。

    使用应用程序路由的 pathFor() 方法,为已命名的路由生成一个 URL 。

    1. echo $app->router->pathFor('hello', [
    2. 'name' => 'Josh'
    3. // Outputs "/hello/Josh"

    路由的 pathFor() 方法接收两个参数:

    • 路由名称
    • 由路由模式占位符及替换值组成的关联数组。

    路由组

    为了帮助将路由整理成条理分明的路由组, \Slim\App 还提供了一个 group() 方法。 每个路由组的路由模式预置于路由或路由组中的路由组,路由组模式的任何占位符参数最终使得嵌套的路由都是可用的:

    1. $app->group('/users/{id:[0-9]+}', function () {
    2. $this->map(['GET', 'DELETE', 'PATCH', 'PUT'], '', function ($request, $response, $args) {
    3. // Find, delete, patch or replace user identified by $args['id']
    4. })->setName('user');
    5. $this->get('/reset-password', function ($request, $response, $args) {
    6. // Route for /users/{id:[0-9]+}/reset-password
    7. // Reset the password for user identified by $args['id']
    8. })->setName('user-password-reset');
    9. });

    记住,在路由组闭包的内部,使用 $this 替代 $app 。Slim 将闭包绑定到应用程序实例,就像路由回调的情况那样。

    你可以将中间件与任意路由或路由组相连接。 了解更多.

    容器识别 / Container Resolution

    你不必限于为路由定义函数。在 Slim 中,有一些不同的方式来定义你的路由行为函数。

    除了函数外,你还可以使用: - 可调用的类 - Class:method

    这个函数由 Slim 的 Callable 解角器(Resolver) 类提供支持。它将字符串入口(entry)转变为函数调用。例如:

    1. $app->get('/home', '\HomeController:home');

    在上面这段代码中,我们定义了一个 /home 路由,并告诉 Slim 执行 \HomeController 类中的 home() 方法。

    Slim 首先在容器中寻找 \HomeController 的入口,如果找到了,它将使用该实例。否则,它将它的构造函数,并将容器作为第一个参数。一旦这个类的实例创建了,它将使用你已定义的策略(Strategy)去调用指定的方法。

    作为另一种办法,你可以使用一个可调用的(invokable)类,比如:

    1. class MyAction {
    2. protected $ci;
    3. //Constructor
    4. public function __construct(ContainerInterface $ci) {
    5. $this->ci = $ci;
    6. }
    7. public function __invoke($request, $response, $args) {
    8. //your code
    9. //to access items in the container... $this->ci->get('');
    10. }
    11. }

    你可以这样使用这个累:

    1. $app->get('/home', '\MyAction');
    1. class MyController {
    2. protected $ci;
    3. //Constructor
    4. public function __construct(ContainerInterface $ci) {
    5. $this->ci = $ci;
    6. }
    7. public function method1($request, $response, $args) {
    8. //your code
    9. //to access items in the container... $this->ci->get('');
    10. }
    11. public function method2($request, $response, $args) {
    12. //your code
    13. //to access items in the container... $this->ci->get('');
    14. }
    15. public function method3($request, $response, $args) {
    16. //your code
    17. //to access items in the container... $this->ci->get('');
    18. }
    19. }

    你可以这样使用控制器方法:

    1. $app->get('/method1', '\MyController:method1');