URL尾部 /


Slim对待一个路由中路由匹配模式有没有尾随着 / 是不一样的。也就是说 /users/users/ 是不一样的,可以绑定不同的回调处理。

如果你想让尾部有带 / 的重定向到不带 / 的,可以添加下面的中间件。

use Psr\Http\Message\RequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;

$app->add(function (Request $request, Response $response, callable $next) {
		$uri = $request->getUri();
		$path = $uri->getPath();
		if ($path != '/' && substr($path, -1) == '/') {
				// permanently redirect paths with a trailing slash
				// to their non-trailing counterpart
				$uri = $uri->withPath(substr($path, 0, -1));
				return $response->withRedirect((string)$uri, 301);
		}

		return $next($request, $response);
});

另外,你也可以考虑 oscarotero/psr7-middlewares’ TrailingSlash 中间件,它允许你强制添加一个 / 到所有的url:

use Psr7Middlewares\Middleware\TrailingSlash;

$app->add(new TrailingSlash(true)); // true adds the trailing slash (false removes it)

检索IP地址


最好的检索当前客户Ip的方式就是利用中间件使用组件,例如:rka-ip-address-middleware

通过Compoer 安装组件:

composer require akrabat/rka-ip-address-middleware

要使用它,首先得注册应用中间件,提供一个可允许访问的ip数组,然后使用:

$checkProxyHeaders = true;
$trustedProxies = ['10.0.0.1', '10.0.0.2'];
$app->add(new RKA\Middleware\IpAddress($checkProxyHeaders, $trustedProxies));

$app->get('/', function ($request, $response, $args) {
		$ipAddress = $request->getAttribute('ip_address');

		return $response;
});

中间件把客户端的IP存储在了请求里面,因此可以使用 $request->getAttribute('ip_address')

检测当前路由


如果你需要在你的应用里面获得当前访问的路由,可以通过请求对象的方法 getAttribute 带一个 route 参数,它是 Slim\Route 类的实现,会返回当前的路由。

然后你可以通过它获得当前路由的名称,通过方法 getName() 还可以获得当前路由可以使用的方法,用 getMethods() 获得。

注意:如果要获得路由通过中间件,你必须配置 determineRouteBeforeAppMiddlewaretrue ,否则getAttribute('route') 会返回 null,路由都是可以支持中间件使用的。

示例:

use Slim\Http\Request;
use Slim\Http\Response;
use Slim\App;

$app = new App([
		'settings' => [
				// Only set this if you need access to route within middleware
				'determineRouteBeforeAppMiddleware' => true
		]
])

// routes...
$app->add(function (Request $request, Response $response, callable $next) {
		$route = $request->getAttribute('route');
		$name = $route->getName();
		$group = $route->getGroup();
		$methods = $route->getMethods();
		$arguments = $route->getArguments();

		// do something with that information

		return $next($request, $response);
});

文档翻译的并不是很专业,仅供个人学习作用,建议看官方文档。

如有兴趣,请看下一篇 SLIM 3 文档(十二)-模板6)