简体   繁体   中英

Why are two controller methods being called in CodeIgniter?

Should I not be using Index as the name for a controller class in CodeIgniter? I have an Index controller, and I'm seeing its methods being called multiple times. More specifically, I always see its index method called first, whether or not I'm visiting a path that should be routed there.

In application/controllers/index.php

class Index extends CI_Controller
{
    public function index()
    {
        echo "index";
    }
    public function blah()
    {
        echo "blah";
    }
}

When I visit index/blah , I see indexblah printed. When I visit index/index , I see indexindex . If I rename the controller to something else (eg Foo), it doesn't have a problem. That's the obvious workaround, but can anyone tell me why this is happening? Should I report this as a bug to CodeIgniter?

(Notes: I have no routes set up in configs/routes.php ; my index.php is outside the CodeIgniter tree)

can anyone tell me why this is happening?

When your controller get's instantiated, index as the constructor is getting called.

Compare Constructors and Destructors Docs :

For backwards compatibility, if PHP 5 cannot find a __construct() function for a given class, it will search for the old-style constructor function, by the name of the class . [highlighting by me]

In your case your Controller does not have any __construct() function but a function that has the same name as the class: index . It is getting called in the moment Codeigniter resolves and loads and then instantiates your Index Controller.

You can solve this by just adding the constructor to your Controller:

class Index extends CI_Controller
{
    public function __construct() {}
    public function index()
    {
        echo "index";
    }
    public function blah()
    {
        echo "blah";
    }
}

After this change, it does not happen again.

Should I report this as a bug to CodeIgniter?

No, there is not really a need to report this as a bug, it's how the language work and as Codeigniter supports PHP 4 it must remain backwards compatible and needs to offer PHP 4 constructors. (Note: The Codeigniter project documents, they need server support for PHP version 5.1.6 or newer, but the actual code has PHP 4 compatiblity build in, I'm referring to the codebase here, not the documentation.)

To further clarify what the issue is, in PHP4 Constructors were a function that had the same name as the Class...

example

class MyClass
{
    public function MyClass()
    {
        // as a constructor, this function is called every 
        // time a new "MyClass" object is created
    }
}

Now for the PHP5 version (Which codeigniter now, as of 2.0.x, holds as a system requirement)

class MyClass
{
    public function __construct()
    {
        // as a constructor, this function is called every 
        // time a new "MyClass" object is created
    }
}

So To answer the question that addresses the problem...

Should I not be using Index as the name for a controller class in CodeIgniter?

I believe it would be best to not choose Index as a controller name as the index() function has a reserved use in codeigniter. This could cause issues depending on your PHP configuration.

Here is another solution using Codeigniter3

require_once 'Base.php';
        class Index extends Base
    {
        public function __construct()
        {
        parent::index();
        $classname=$this->router->fetch_class();
    $actioname=$this->router->fetch_method();

    if($actioname=='index' || $actioname == '')
    {
        $this->viewall();
    }
}
}

And the viewall() had the following

$this->siteinfo['site_title'].=' | Welcome';
$this->load->view('templates/header', $this->siteinfo);
$this->load->view('templates/menu', $this->siteinfo);
$this->load->view('index/viewall', $data);
$this->load->view('templates/footer', $this->siteinfo);

The Base controller does all the library and helper loading for the entire application which is why it is being required in the default class

Basically from my short understanding of CodeIgniter, having a default action as index is a wrong. I found this out by using the printing the result of $this->router->fetch_method(); in the construct() of my index class. The default action by CodeIgniter is index, you may only set the default controller within application/config/routes.php and not the default action.

So my advice, never use index() as the default action especially if you are using index as the default controller

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM