Optional parameter in named routes

in Quick Bites


Let's say you want to make a named CakePHP route which may or may not have an argument. For example, you want to return WHOIS information for an IP address:

  • /whois/1.1.1.1 returns WHOIS information for 1.1.1.1 which is specifically passed in the URL;
  • /whois will return WHOIS information for the visitor's IP address.

When doing a quick search, I found this somewhat related Github issue, where devs said it's not possible and suggested OP defines two separate routes instead: one with the argument and the other one without it.

The problem with a named route is that names must be unique, same name cannot be used twice.

Here's the working config for a named route that accepts an optional argument and if it's not present, defaults it to empty.

In your config/routes.php:

$routes->connect(
    '/whois/{ip}',
    [
        //'plugin' => $this->getName(),// use if you're inside a plugin
        //'prefix' => 'Admin',//use if route needs to be inside a prefix
        'controller' => 'Whois',
        'action' => 'getinfo',
        'ip' => '', // defaults to empty
    ],
    [
        '_name' => 'ipwhois',
    ]
)->setPass(['ip']);

Now you can call this route in your scripts elsewhere in the application:

  • echo \Cake\Routing\Router::url(['_name' => 'ipwhois']);
  • echo \Cake\Routing\Router::url(['_name' => 'ipwhois', 'ip' => $this->getRequest()->clientIp()]);