germania-kg/routenameurlcallable

使用 RouteContext 和 RouteParser 生成 Slim 4 命名路由的完整 URL,适用于 Twig 函数

2.3.0 2023-01-06 13:00 UTC

README

Germania KG · RouteNameUrlCallable

用于使用 Slim 4 的 RouteContextRouteParser 生成完整 URL 的可调用函数。作为 Twig 函数运行良好。

Packagist PHP version Tests

使用 Composer 安装

此包需要 Slim 框架 4。如果要使用 Slim 框架 3,请检查 v1 分支。

$ composer require germania-kg/routenameurlcallable "^2.0"

或者,将此包直接添加到您的 composer.json:

"require": {
    "germania-kg/routenameurlcallable": "^2.0"
}

介绍

在 Slim 路由中的控制器可调用函数有时需要一个完整的 URL,无论是用于重定向响应还是用于渲染链接。考虑这个通过 POST 创建新 thing 并重定向到其 GET 表示形式的路由。重定向需要完整的 URL。

给定一个这样的 命名 Slim 路由

$app->get("/hello/{name}", function($request, $response, $args) {
  $response->getBody()->write("Hello " . $args['name'] );
  return $response;
})->setName("Hello");

Slim 框架 提供了使用 RouteContextRouteParser 的解决方案

$app->post("/users", function($request, $response, $args) {
  // Create new user and grab name
  $user = "john";
  $route = "Hello";
  
  // The Slim way
  $uri      = $request->getUri();
  $context  = \Slim\Routing\RouteContext::fromRequest($request);
  $parser   = $context->getRouteParser();
  $location = $parser->fullUrlFor($uri, $route, ['name' => $user]);
  # http://test.com/hello/john
  
  return $response->withHeader('Location', $location)->withStatus(302);
});

RouteNameUrlCallable 现在隐藏了繁琐的部分。它基本上是一个快捷方式

$app->post("/users", function($request, $response, $args) {
  
  // Create new user and grab name
  $user = "john";
  $route = "Hello";
  
  $uri_factory = new RouteNameUrlCallable($request);  
  $location = $uri_factory($route, ['name' => $user]);
  # http://test.com/hello/john
  
  return $response->withHeader('Location', $location)->withStatus(302);
});

实例化

Slim\Psr7\Request 实例传递给构造函数。这是自发布 2 以来的默认变体。

$rnc = new RouteNameUrlCallable($request);  

自发布 2.2 以来,也可以注入 Slim\Interfaces\RouteParserInterface。这种方式将成为自主要版本 3 (截至编写本文时没有时间表) 的标准。

use Slim\Routing\RouteContext;

$request = ...;
$route_parser = RouteContext::fromRequest($request)->getRouteParser();

$rnc = new RouteNameUrlCallable($route_parser); 

建议:作为将请求注入构造函数的替代方案,鼓励使用静态 fromRequest 方法。

$rnc = RouteNameUrlCallable::fromRequest($request); 

使用方法

虽然 Slim 的 RouteParserrelativeUrlForrelativeUrlForfullUrlFor 方法返回一个字符串,但 RouteNameUrlCallable 返回一个 Slim\Http\Uri 实例

<?php
use Germania\RouteNameUrlCallable\RouteNameUrlCallable;
use Slim\Factory\AppFactory;

// Setup Slim 4 App
$app = AppFactory::create();
$app->addRoutingMiddleware();


// Our named route:
$app->get("/hello/{name}", function($request, $response, $args) {
  $response->getBody()->write("Hello " . $args['name'] );
  return $response;
})->setName("Hello");


// ...and a route we use the callable within:
$app->post("/users", function($request, $response, $args) {

  // Create new user and grab name
  $user = "john";
  $route = "Hello";
  
  $uri_factory = new RouteNameUrlCallable::fromRequest($request);  

  $location = $uri_factory($route, ['name' => $user]);
  echo get_class($location); 
  # \Slim\Http\Uri
  
  echo $login_url->__toString();  
  # http://test.com/hello/john
  
  return $response->withHeader('Location', $location)->withStatus(302);
});

调用替代方案

第一个 RouteNameUrlCallable 参数可以是一个 数组对象,其中包含 nameargsquery 内容。

占位符参数查询参数 可以通过第二个和第三个参数覆盖,这些参数将被合并

$url_data = array(
	'name' => "Hello",
  'args' => ['name' => 'John'],
  'params' => ['foo' => 'bar']
);

echo $uri_factory( $url_data );
http://test.com/hello/john?foo=bar

echo $uri_factory( $url_data, [], ['view' => 'table'] );
http://test.com/hello/john?foo=bar&view=table

echo $uri_factory( $url_data, [], ['foo' => 'baz', 'view' => 'table'] );
http://test.com/hello/john?foo=baz&view=table

与 Twig 一起使用

由于 RouteNameUrlCallable 是可调用的,因此可以在模板内部作为 Twig 函数 使用

{# "hello-user.html" #}
<a href="{{route_url('hello', {'name' => user})}}">Say hello to {{user}}</a>

在您路由控制器内部,像这样添加可调用函数

<?php
$app->get("/", function($request, $response, $args) {
  
  $uri_factory = new RouteNameUrlCallable($request);

  $twig = new \Twig\Environment( ... );
  $twig->addFunction(new \Twig\TwigFunction('route_url', $uri_factory));
  
  $html = $twig->render("hello-user.html", [
    "user" => "john"
  ]);
  
  $response->getBody()->write( $html );

  return $response;
});

开发

$ git clone https://github.com/GermaniaKG/RouteNameUrlCallable.git
$ cd RouteNameUrlCallable
$ composer install

单元测试

要么将 phpunit.xml.dist 复制到 phpunit.xml 并根据您的需要进行调整,要么保持原样。运行 PhpUnit 测试或 composer 脚本如下

$ composer test
# or
$ vendor/bin/phpunit