Маршрутизация имени хоста в Zend Expressive

Zend Expressive имеет адаптеры для Aura.Router, FastRoute и zend-mvc Router, и маршрут может легко соответствовать методу и пути:

<?php
$app->get('/foo', $middleware);

С Маршрутизатор Zend-MVC Компонент может соответствовать имени хоста:

<?php
use Zend\Mvc\Router\Http\Hostname;

$route = Hostname::factory([
'route' => ':subdomain.example.com/foo',
'constraints' => [
'subdomain' => 'api',
],
]);

$router->addRoute('foo', $route);

Это также возможно с Symfony Компонент маршрутизации:

<?php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

$route = new Route(
'/foo', // path
array('_controller' => 'SomeController'), // default values
array('subdomain' => 'api'), // requirements
array(), // options
'{subdomain}.example.com', // host
array(), // schemes
array() // methods
);

$routes = new RouteCollection();
$routes->add('foo', $route);

Итак, я хотел бы иметь возможность сделать что-то подобное с Expressive и отправить запрос на другое промежуточное программное обеспечение в зависимости от субдомена:

// dispatch the requiest to ApiMiddleware
$app->get(':subdomain.example.com/foo', $ApiMiddleware, ['subdomain' => 'api']);

// dispatch the requiest to WebMiddleware
$app->get(':subdomain.example.com/foo', $WebMiddleware, ['subdomain' => 'www']);

Заранее спасибо!

1

Решение

Почему вы не создали новое промежуточное ПО для извлечения запроса и не выбрали, какое промежуточное ПО следует вызывать в конвейере дальше?

Вы могли бы сделать что-то подобное:

Application \ Middleware \ DeciderMiddleware

<?php

namespace Application\Middleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class DeciderMiddleware
{
protected $apiMiddleware;
protected $webMiddleware;

public function __construct(
callable $apiMiddleware,
callable $webMiddleware
) {
$this->apiMiddleware = $apiMiddleware;
$this->webMiddleware = $webMiddleware;
}

public function __invoke(
ServerRequestInterface $request,
ResponseInterface $response,
callable $next = null
) {
if (strpos($request->getUri()->getHost(), 'api.') === 0) {
return ($this->apiMiddleware)($request, $response);
}

if (strpos($request->getUri()->getHost(), 'www.') === 0) {
return ($this->webMiddleware)($request, $response);
}

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

конфигурации / автозагрузка / промежуточного-pipeline.global.php

<?php

return [
'dependencies' => [
'factories' => [
Application\Middleware\DeciderMiddleware::class => Application\Middleware\DeciderMiddlewareFactory::class
],
],
'middleware_pipeline' => [
'always' => [
'middleware' => [
Application\Middleware\DeciderMiddleware::class
],
'priority' => 10000,
],
],
];

Единственное, что вам нужно сделать, это определить apiMiddleware и webMiddleware в DeciderMiddlewareFactory и инициализировать объект DeciderMiddleware с этими параметрами.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]