PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, March 16, 2022

[FIXED] Routing for multiple hosts in Cakephp

 March 16, 2022     cakephp, cakephp-4.x, url-routing     No comments   

Issue

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']);

Solution

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

  • Cookbook > Routing > Custom Route Classes


Answered By - ndm
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing