cakephp: UrlHelper can't match with any defined routes if missing _method option

This is a (multiple allowed):

  • bug

  • enhancement

  • feature-discussion (RFC)

  • CakePHP Version: 3.5.6

  • Platform and Target: PHP built-in webserver

What you did

In routes.php I declared a route like this:

$routes->connect('/login', ['controller' => 'Users', 'action' => 'login'], ['_name' => 'login'])->setMethods(['GET', 'POST']);

In the template file, I uses UrlHelper like this:

$this->Url->build(['_name' => 'login'])

What happened

I get Cake\Routing\Exception\MissingRouteException and an error Warning (2): strtoupper() expects parameter 1 to be string, array given [CORE/src/Routing/Route/Route.php, line 744]

What you expected to happen

It should match with the route that I have declared in routes.php and return /login string. The error will gone if I’m also add _method option like this:

$this->Url->build(['_name' => 'login', '_method' => 'GET'])

I think it should not matter what http method will be used the url to be generated is /login

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 17 (16 by maintainers)

Commits related to this issue

Most upvoted comments

@beporter Any chance you could put a pull request together with that change?

I can care to this

@saeideng I don’t use custom route class. I use built-in DashedRoute class. @markstory _method become an array because:

  • I call this method ->setMethods(['GET', 'POST']) in routes.php. It will set default method to an array ['GET', 'POST'].
  • I don’t provide the _method option when calling Url::build(). I don’t provide it because I use named route, that what I expect is only need to pass the _name option.
  • At this line, https://github.com/cakephp/cakephp/blob/3.5.6/src/Routing/RouteCollection.php#L316 will use default _method which is an array. Here is var_dump output of $route->defaults
array (
  'controller' => 'Users',
  'action' => 'login',
  'plugin' => NULL,
  '_method' => 
  array (
    0 => 'GET',
    1 => 'POST',
  ),
)