I have a project with a GET route included in the ‘Routes.php’ file and the rest of the routes generated by autorouting, that is, access to the methods of the controllers from the URL.
These controllers are included in a module. I created the following directory structure:
app
├── Config
│ └── Routes.php (refers to the routes created in each module folder /Config/Routes.php)
├── Modules
│ └── Slink
| ├── Config
| └── Routes.php (Added a group with a single route)
│ ├── Controllers
│ ├── Home.php
| └── Shortener.php
│ ├── Models
│ └── Slink.php
│ └── Views
│ ├── not_found.php
| └── welcome_message.php
└── ...
The code in app\Config\Routes.php
is:
<?php
use CodeIgniter\Router\RouteCollection;
/**
* @var RouteCollection $routes
*/
$modules_path = APPPATH . 'Modules/';
$modules = scandir($modules_path);
foreach ($modules as $module) {
if ($module === '.' || $module === '..') {
continue;
}
if (is_dir($modules_path) . '/' . $module) {
$routes_path = $modules_path . $module . '/Config/Routes.php';
if (file_exists($routes_path)) {
require $routes_path;
} else {
continue;
}
}
}
And the code in app\Modules\Slink\Config\Routes.php
is the following:
<?php
namespace App\Modules\Slink\Config;
use CodeIgniter\Router\RouteCollection;
/**
* @var RouteCollection $routes
*/
$routes->group(
'', ['namespace' => 'App\Modules\Slink\Controllers'], function ($routes) {
$routes->get('/', 'Home::welcome');
}
);
When I try to access the GET route from the browser (http://localhost:8080/
), it returns the expected result (content from the method welcome()
in the Controller app\Modules\Slink\Controllers\Home.php
) , but when I use the class/method route, it returns a 404 error (for example: http://localhost:8080/shortener/prueba
). Do you know what could be happening?
The content of Controller app\Modules\Slink\Controllers\Shortener.php
is:
<?php
namespace App\Modules\Slink\Controllers;
use App\Controllers\BaseController;
class Shortener extends BaseController
{
public function prueba()
{
echo "HOLA MUNDO";
}
}
And the content of Controller app\Modules\Slink\Controllers\Home.php
is the following:
<?php
namespace App\Modules\Slink\Controllers;
use App\Controllers\BaseController;
class Home extends BaseController
{
public function welcome(): string
{
return view('../Modules/Slink/Views/welcome_message');
}
}
Result to try to access class/method route in the browser:
Attached is the result of the php spark routes
command (where everything looks correct).
CodeIgniter v4.5.5 Command Line Tool - Server Time: 2025-01-27 13:33:43 UTC+00:00
+--------+-----------------------------+------+-------------------------------------------------------+----------------+---------------+
| Method | Route | Name | Handler | Before Filters | After Filters |
+--------+-----------------------------+------+-------------------------------------------------------+----------------+---------------+
| GET | / | » | \App\Modules\Slink\Controllers\Home::welcome | | |
| auto | home/welcome[/...] | | \App\Modules\Slink\Controllers\Home::welcome | <unknown> | <unknown> |
| auto | shortener/prueba[/...] | | \App\Modules\Slink\Controllers\Shortener::prueba | <unknown> | <unknown> |
+--------+-----------------------------+------+-------------------------------------------------------+----------------+---------------+
Required Before Filters: forcehttps, pagecache
Required After Filters: pagecache, performance, toolbar
As the userguide suggests for Controllers (github.io) outside of the main app/Controllers
directory, they cannot be automatically routed by URI detection.
Given your routes registration:
$routes->group(
'', ['namespace' => 'App\Modules\Slink\Controllers'], function ($routes) {
$routes->get('/', 'Home::welcome');
}
);
You manage to set the default namespace to App\Modules\Slink\Controllers
so that Home::welcome
can be resolved to App\Modules\Slink\Controllers\Home::welcome
which suffices to register the route for it, however you do not add the controller you're currently missing.
What the spark routes
function shows is that you successfully managed to register the default namespace for the controllers, which suffices for discovery of the routes, but the routing is only effective if the controller file is in the app/Controllers
directory as unless the route can not be resolved (and henceforth you get a 404 File Not Found error).
Just add the routes you'd actually like to configure:
$routes->group(
'', ['namespace' => 'App\Modules\Slink\Controllers'], function ($routes) {
$routes->get('home/welcome', 'Home::welcome');
$routes->get('shortener/prueba', 'Shortener::prueba');
}
);
Or write your controllers as documented and in the places to work with autorouting (legacy).
Additionally I'd recommend to also follow the suggestion about placing your module alongside the ./app
directory, not inside:
+ raulizbu/slink/...
+ app/...
See Code Modules (github.io), this should also help you not needing relying on self-written file discovery for your routes etc. as all you need to configure is the autoloading which also works per your projects composer.json instead of needing to hack the ./app/Config/Autoload.php
file.