0

正如食谱所说:

路由可以使用 _host 选项仅匹配特定主机。您可以使用 *. 通配符匹配任何子域。

但是,如果我想一次为多个主机设置相同的路由怎么办?

例如:

$routes->connect(
    '/images',        
    ['controller' => 'Images', 'action' => 'index']
)->setHost('images.example.com');

$routes->connect(
    '/images',        
    ['controller' => 'Images', 'action' => 'index']
)->setHost('images.example2.com');

$routes->connect(
    '/images',        
    ['controller' => 'Images', 'action' => 'index']
)->setHost('images.example3.com');

如果我必须设置几十条这样的路线,上面是没有意义的。

理想是这样的:

$routes->connect(
    '/images',        
    ['controller' => 'Images', 'action' => 'index']
)->setHosts(['images.example.com','images.example2.com','images.example3.com']);
4

1 回答 1

2

这是不支持的,您要么必须相应地设置多个路由,您可以简单地在循环中执行您提供主机列表的操作:

foreach (['images.example.com','images.example2.com','images.example3.com'] as $host) {
    $routes
        ->connect(
            '/images',        
            ['controller' => 'Images', 'action' => 'index']
        )
        ->setHost($host);
}

或者创建一个自定义路由类来接受多个主机,或者可能是实际的正则表达式。后者可能会更容易,因为它不需要重新实现很多匹配的东西,比如:

src/路由/路由/RegexHostRoute.php

namespace App\Routing\Route;

use Cake\Routing\Route\DashedRoute;

class RegexHostRoute extends DashedRoute
{
    public function match(array $url, array $context = []): ?string
    {
        // avoids trying to match the _host option against itself in parent::match()
        if (!isset($url['_host'])) {
            return null;
        }

        return parent::match($url, $context);
    }

    public function hostMatches(string $host): bool
    {
        return preg_match('^@' . $this->options['_host'] . '@$', $host) === 1;
    }
}

这应该允许设置一个主机,如images\.example[2-3]?\.com

$routes
    ->connect(
        '/images',        
        ['controller' => 'Images', 'action' => 'index'],
        ['routeClass' => \App\Routing\Route\RegexHostRoute::class]
    )
    ->setHost('images\.example[2-3]?\.com');

也可以看看

于 2020-01-09T14:27:24.793 回答