codeigniter4 / CodeIgniter4

Open Source PHP Framework (originally from EllisLab)
https://codeigniter.com/
MIT License
5.4k stars 1.9k forks source link

Bug: There are cases where the name of a named route is not determined. #8039

Closed tomomo closed 1 year ago

tomomo commented 1 year ago

PHP Version

8.2

CodeIgniter4 Version

4.4.1

CodeIgniter4 Installation Method

Composer (using codeigniter4/appstarter)

Which operating systems have you tested for this bug?

macOS

Which server did you use?

apache

Database

No response

What happened?

There are cases where the name of a named route is not determined. Unnamed or duplicate.

# app/Config/Routes.php
$routes->get('login', [AuthController::class, 'showLogin'], ['as' => 'loginShow']);
$routes->post('login', [AuthController::class, 'login'], ['as' => 'login']);
$routes->get('logout', [AuthController::class, 'logout'], ['as' => 'logout']);
php spark routes

CodeIgniter v4.4.1 Command Line Tool - Server Time: 2023-10-13 02:07:54 UTC+00:00

+--------+--------+-----------+--------------------------------------------+----------------+---------------+
| Method | Route  | Name      | Handler                                    | Before Filters | After Filters |
+--------+--------+-----------+--------------------------------------------+----------------+---------------+
| GET    | /      | »         | \App\Controllers\Home::index               |                | toolbar       |
| GET    | login  | loginShow | \App\Controllers\AuthController::showLogin |                | toolbar       |
| GET    | logout | »         | \App\Controllers\AuthController::logout    |                | toolbar       |
| POST   | login  | loginShow | \App\Controllers\AuthController::login     |                | toolbar       |
+--------+--------+-----------+--------------------------------------------+----------------+---------------+

"logout" cannot be named. "login(GET or POST") has the same name.(Is this the specification?)

Steps to Reproduce

Add the following to app/Config/Routes.php

# app/Config/Routes.php
$routes->get('login', [AuthController::class, 'showLogin'], ['as' => 'loginShow']);
$routes->post('login', [AuthController::class, 'login'], ['as' => 'login']);
$routes->get('logout', [AuthController::class, 'logout'], ['as' => 'logout']);

Expected Output

Check with php spark routes etc.

php spark routes

CodeIgniter v4.4.1 Command Line Tool - Server Time: 2023-10-13 02:07:54 UTC+00:00

+--------+--------+-----------+--------------------------------------------+----------------+---------------+
| Method | Route  | Name      | Handler                                    | Before Filters | After Filters |
+--------+--------+-----------+--------------------------------------------+----------------+---------------+
| GET    | /      | »         | \App\Controllers\Home::index               |                | toolbar       |
| GET    | login  | loginShow | \App\Controllers\AuthController::showLogin |                | toolbar       |
| GET    | logout | »         | \App\Controllers\AuthController::logout    |                | toolbar       |
| POST   | login  | loginShow | \App\Controllers\AuthController::login     |                | toolbar       |
+--------+--------+-----------+--------------------------------------------+----------------+---------------+

"logout" cannot be named. "login(GET or POST") has the same name.(Is this the specification?)

Anything else?

No response

kenjis commented 1 year ago

Thank you for reporting. This seems to be a bug in the spark routes command.

Try:

--- a/system/Router/DefinedRouteCollector.php
+++ b/system/Router/DefinedRouteCollector.php
@@ -57,7 +57,7 @@ final class DefinedRouteCollector
                         $handler = $view ? '(View) ' . $view : '(Closure)';
                     }

-                    $routeName = $this->routeCollection->getRoutesOptions($route)['as'] ?? $route;
+                    $routeName = $this->routeCollection->getRoutesOptions($route, $method)['as'] ?? $route;

                     yield [
                         'method'  => $method,
tomomo commented 1 year ago

Thank you for your prompt reply. When I tried replacing it, I got the following result.

+--------+--------+-----------+--------------------------------------------+----------------+---------------+
| Method | Route  | Name      | Handler                                    | Before Filters | After Filters |
+--------+--------+-----------+--------------------------------------------+----------------+---------------+
| GET    | /      | »         | \App\Controllers\Home::index               |                | toolbar       |
| GET    | login  | loginShow | \App\Controllers\AuthController::showLogin |                | toolbar       |
| GET    | logout | »         | \App\Controllers\AuthController::logout    |                | toolbar       |
| POST   | login  | »         | \App\Controllers\AuthController::login     |                | toolbar       |
+--------+--------+-----------+--------------------------------------------+----------------+---------------+

I confirmed that there was a change in login (POST). I also found out that if Route and Name are the same, the name will be the "»" symbol. I think it's working well.

kenjis commented 1 year ago

Thank you for checking. I sent a PR to fix: #8040