Managing routes and URLs in CodeIgniter 4

- Andrés Cruz

En español
Managing routes and URLs in CodeIgniter 4

CodeIgniter 4, as the modern framework that it is, has developed a complete system to handle routes, something that has been around for a long time in other frameworks such as Laravel or Django, in which we have an additional layer or level to handle routes, so So, we have a mechanism to indicate which controller function is going to process which URL via the routes.

Already in the previous entry we saw how we can take the first steps with CodeIgniter 4 and work with controllers and functions, in addition to creating our first controller and associated function and a get route.

Composition of the routes

As it happens in most of the frameworks that work with the routing layer, they basically define 3 basic parameters:

  1. The URI
  2. The controller
  3. The function inside the controller, which is the one that will be in charge of doing the process

In addition to the type of route that we talk about a little further down, which for this example is of the post type:

$routes->post('/save_form', 'Admin::save');

Type of routes

In Codeigniter 4, we have multiple types of routes that we can use depending on the method to be used, that is, if we use get type routes, it means that they will only be able to resolve type requests, get, now if we are interested in sending a message, We generally use it to, for example, save data from a form, we have to create a post type route:

$routes->post('/save_form', 'Admin::save');

Therefore, if we try to access this route of type post through a query from the browser, it will give us the following error:

Ruta 404 post

Simply a 404 because we are accessing a method through a get request that is only configured to be accessed via post.

So, we have to define another route as get, or we just add another route for the get:

$routes->get('/save_form', 'Admin::save'); $routes->post('/save_form', 'Admin::save');

And with this, for the following function:

public function save(){return "save";    }

We have the expected result:

Ruta correcta get

Because the above route works to be consumed by both get and post.

Of course, we also have for those of the put, patch or delete type:

$routes->get('products', 'Product::feature'); $routes->post('products', 'Product::feature'); $routes->put('products/(:num)', 'Product::feature'); $routes->patch('products/(:num)', 'Product::feature'); $routes->delete('products/(:num)', 'Product::feature');

That we can use them depending on the type of operation we want to perform.

Group routes

In case we have several routes with part of the same URI the same; for example, suppose now we will say that our route has the word admin in it:

$routes->group('admin', function ($routes) {    $routes->get('save_form', 'Admin::save');    $routes->post('save_form', 'Admin::save'); });

Now we have to add an admin to the path; in my case:


Ruta de tipo get y post

You can add as many grouping levels as you want or need:

$routes->group('admin', function ($routes) {    $routes->group('user', function ($routes) {        $routes->get('save_form', 'Admin::save');        $routes->post('save_form', 'Admin::save');    }); });

And to access it:


And we want to create another route:

$routes->group('admin', function ($routes) {    $routes->group('user', function ($routes) {        $routes->get('save_form', 'Admin::save');        $routes->post('save_form', 'Admin::save');        $routes->get('index', 'Admin::index');    }); });

We can perfectly do:


And with the following function in our controller:

public function index()    {        return "Admin";    }

We have the following:

Ruta get index

Parameters for routes and urls

We can also define parameters to routes to pass additional data; for example a number:

$routes->get('save_form/(:num)', 'Admin::save/$1', ['as' => 'admin_save']);

From the function:

public function save($id)    {        return "save: ".$id;    }


We can configure different placeholders depending on the type of data we want to receive:

(:any)It will match any character that we pass to it through the URL.
(:segment)Same as above excluding the /.
(:num)Match with any integer.
(:alpha)Match with any character of the alphabet.
(:alphanum)Match with any character of the alphabet or number.

Named routes

We can also give our route a name, later, in another entry we will see a practical example of all this, but suppose that it is simply a reference that we give it to be able to refer to the route through the name and NOT directly place the URI ; the advantage of this is self-explanatory and in this way we can perfectly vary the URI without needing to update the reference in our code:

$routes->get('save_form', 'Admin::save', ['as' => 'admin_save']);

And from a view; we simply place the reference to the name:

<?= route_to('admin_save') ?>

If I received arguments:

<?= route_to('admin_save', $movie->id) ?>

Define our routes for a CRUD type operation

The most common thing in systems is that we need to perform CRUD type operations, that is, to create, read, update and delete an entity, as you can see, for example, for the create and update view we need to define two post routes each of these operations, one to display the form and another to process the information plus the view for the list would be a total of 7 different routes to perform a generic operation such as doing a CRUD; Luckily modern frameworks such as CodeIgniter 4, we have a method that allows us to define through a single function or method all the types of routes that we need:

$routes->resource('photos', $options);

You can see the routes that we have to specify in the official documentation.

Common routes

In C4, we can say that the common routes to use in any application are:

$routes->get('pelicula','Pelicula::index'); // De tipo get para generar un listado de elementos

$routes->get('pelicula/new','Pelicula::new'); // De tipo get para pintar el formulario de creación
$routes->post('pelicula','Pelicula::create');// De tipo create para procesar el formulario al momento de crear un recurso

$routes->get('pelicula/xx/edit','Pelicula::edit');// De tipo get para pintar el formulario para editar un elemento
$routes->put('pelicula/xx','Pelicula::update');// de tipo put para procesar todo el formulario de un registro existente

$routes->delete('pelicula/xx','Pelicula::delete'); // de tipo delete que como sorpresa, permite eliminar un registro

The previous scheme is the URIs used par excellence to carry out each of the indicated operations and the types of common routes to carry out the famous CRUD at the application level.

View generated routes

In order to see the routes generated at the application level, we have the spark command:

php spark routes

Generate routes automatically

A very interesting feature that CodeIgniter has is being able to generate routes automatically, according to the methods that we have registered, for this, in our routes file, we have to enable it:


Given the following controller:

namespace App\Controllers;

class Pelicula extends BaseController {

    public function index()
        echo "Hola Mundo";
    public function test($x = 0,$n = 10)
        echo "Hola Mundo test ".$x." ".$n;

    // public function new()
    // {
    //    echo view("pelicula/create");
    // }

    // public function create()
    // {
    //     echo "Procesando el Form!";
    // }
    public function edit($id)
       echo view("pelicula/edit");

    public function update($id)
        echo "Procesando el Form! ".$id;


And remove the previously defined routes and check which routes have been generated:

| Method | Route                 | Handler                                  |
| auto   | /                     | \App\Controllers\Home::index             |
| auto   | home                  | \App\Controllers\Home::index             |
| auto   | home/index[/...]      | \App\Controllers\Home::index             |
| auto   | pelicula              | \App\Controllers\Pelicula::index         |
| auto   | pelicula/index[/...]  | \App\Controllers\Pelicula::index         |
| auto   | pelicula/test[/...]   | \App\Controllers\Pelicula::test          |
| auto   | pelicula/edit[/...]   | \App\Controllers\Pelicula::edit          |
| auto   | pelicula/update[/...] | \App\Controllers\Pelicula::update        |

This is a particularly useful option when you have an application in which you can take advantage of this type of feature.

Remember that if you want more you can take my course in CodeIgniter 4 from a link that I leave you in my Blog.

Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy

Acepto recibir anuncios de interes sobre este Blog.

!Cursos a!


En Udemy

Quedan 0 días!


!Cursos desde!


En Academia

Ver los cursos

!Libros desde!


Ver los libros
¡Hazte afiliado en Gumroad!
!Web Alojada en Hostinger!