Cakephp 中多个主机的路由
Routing for multiple hosts in Cakephp
正如食谱所说:
Routes can use the _host option to only match specific hosts. You can use the *. wildcard to match any subdomain.
但是如果我想一次为多个主机设置相同的路由怎么办?
例如:
$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']);
这是不支持的,您要么必须相应地设置多条路由,您可以简单地在一个循环中执行,并提供您的主机列表:
foreach (['images.example.com','images.example2.com','images.example3.com'] as $host) {
$routes
->connect(
'/images',
['controller' => 'Images', 'action' => 'index']
)
->setHost($host);
}
或者创建一个自定义路由 class 接受多个主机,或者可能是实际的正则表达式。后者可能会更容易,因为它不需要重新实现很多匹配的东西,比如:
src/Routing/Route/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');
另见
正如食谱所说:
Routes can use the _host option to only match specific hosts. You can use the *. wildcard to match any subdomain.
但是如果我想一次为多个主机设置相同的路由怎么办?
例如:
$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']);
这是不支持的,您要么必须相应地设置多条路由,您可以简单地在一个循环中执行,并提供您的主机列表:
foreach (['images.example.com','images.example2.com','images.example3.com'] as $host) {
$routes
->connect(
'/images',
['controller' => 'Images', 'action' => 'index']
)
->setHost($host);
}
或者创建一个自定义路由 class 接受多个主机,或者可能是实际的正则表达式。后者可能会更容易,因为它不需要重新实现很多匹配的东西,比如:
src/Routing/Route/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');
另见