As cookbook says:
Routes can use the _host option to only match specific hosts. You can use the *. wildcard to match any subdomain.
But what if I would like set same route for multiple hosts at once?
For example:
$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');
Above is pointless if I have to set several dozen of those routes.
Ideal would be something like this:
$routes->connect(
'/images',
['controller' => 'Images', 'action' => 'index']
)->setHosts(['images.example.com','images.example2.com','images.example3.com']);
That's not supported, you'll either have to set multiple routes accordingly, which you could simply do in a loop that you feed a list of your hosts:
foreach (['images.example.com','images.example2.com','images.example3.com'] as $host) {
$routes
->connect(
'/images',
['controller' => 'Images', 'action' => 'index']
)
->setHost($host);
}
or create a custom route class that accepts either multiple hosts, or maybe actual regular expressions. The latter would probably be easier, as it wouldn't require reimplementing a lot of stuff for matching, something like:
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;
}
}
That should allow to set a host like images\.example[2-3]?\.com
:
$routes
->connect(
'/images',
['controller' => 'Images', 'action' => 'index'],
['routeClass' => \App\Routing\Route\RegexHostRoute::class]
)
->setHost('images\.example[2-3]?\.com');
See also