tariq
tariq

Reputation: 109

CodeIgniter class repeated in url allowed

With a fresh install of CodeIgniter 2 and untouched welcome.php as follows:

class Welcome extends CI_Controller {
    public function index()
    {
        $this->load->view('welcome_message');
    }
}

and the following requests:

url                                http response expected   actual
/index.php/welcome                               200        200
/index.php/welcome/wtf                           404        404
/index.php/welcome/welcome                       404        200 ?
/index.php/welcome/welcome/welcome               404        200 ?
/index.php/welcome/welcome/welcome/welcome       404        200 ?
/index.php/welcome/welcome/wtf                   404        200 ?

Note the last four requests. Why does CodeIgniter exhibit this behaviour? Is it possible to disable?

My naive quick fix is below, but wondering if there is something that can be changed globally to address other controllers.

class Welcome extends CI_Controller {
    public function index()
    {

        $this->load->helper('url');

        if (strpos(uri_string(), 'welcome/welcome') !== false) {
            show_404();
        }

        $this->load->view('welcome_message');
    }
}

Upvotes: 1

Views: 113

Answers (2)

Gwendal
Gwendal

Reputation: 1273

After looking in CI's code, I think this is caused by the fetch_method function of CI_Router class. Look :

function fetch_method()
{
    if ($this->method == $this->fetch_class())
    {
        return 'index';
    }

    return $this->method;
}

So, the default behavior of the router is to set the method to index if method's name is equal to class' name.

You should be able to override this by creating a MY_Router.php file in your core folder.

<?php

class MY_Router extends CI_Router {

    function fetch_method()
    {
        return $this->method;
    }
}

Upvotes: 1

Alex
Alex

Reputation: 9265

My guess is that the 2nd welcome must act as an alias for index which is why it is working. So it evaluates to welcome(controller)/welcome(index/method)/param(passed to method). But don't quote me on this as I'm not familiar with CI2.

You might be able to do something like this (using your code):

class MY_Controller extends CI_Controller {

    public function __construct() {

        $this->load->helper('url');

        $seg1 = $this->uri->segment(1);
        $seg2 = $this->uri->segment(2);

        if (strpos(uri_string(), "{$seg1}/{$seg2}") !== false) {
            show_404();
        }

    }

}

all controllers would have to extend MY_Controller which would be stored in application/core

Upvotes: 0

Related Questions