为什么在CodeIgniter中调用两个控制器方法?

时间:2011-08-08 16:48:30

标签: php codeigniter controller

我不应该使用Index作为CodeIgniter中控制器类的名称吗?我有一个索引控制器,我看到它的方法被多次调用。更具体地说,我总是看到它的index方法首先被调用,无论我是否正在访问应该在那里路由的路径。

在application / controllers / index.php

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

当我访问index/blah时,我看到indexblah已打印出来。当我访问index/index时,我看到indexindex。如果我将控制器重命名为其他东西(例如Foo),它就没有问题。这是明显的解决方法,但任何人都可以告诉我为什么会这样吗?我应该将此报告为CodeIgniter的错误吗?

(注意:我在configs/routes.php中没有设置路由;我的index.php在CodeIgniter树之外)

3 个答案:

答案 0 :(得分:2)

  

谁能告诉我为什么会这样?

当你的控制器被实例化时,index随着构造函数被调用。

比较Constructors and DestructorsDocs

  

为了向后兼容,如果PHP 5找不到给定类的__construct()函数,它将搜索旧式构造函数,按类的名称。 [由我强调]

在您的情况下,您的Controller没有任何__construct()函数,而是一个与该类名称相同的函数:index。在Codeigniter解析并加载然后实例化您的Index控制器的那一刻,它就会被调用。

只需将构造函数添加到Controller即可解决此问题:

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

在此更改后,它不会再次发生。

  

我应该将此报告为CodeIgniter的错误吗?

不,没有必要将此报告为错误,这是语言的工作方式,而Codeigniter支持PHP 4,它必须保持向后兼容,并且需要提供PHP 4构造函数。 (注意:Codeigniter项目文档,他们需要PHP版本5.1.6或更新版本的服务器支持,但实际代码内置了PHP 4兼容性,我在这里指的是代码库,而不是文档。)

答案 1 :(得分:2)

为了进一步说明问题所在,在PHP4中,构造函数是一个与类相同的函数...

示例

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

现在为PHP5版本(现在哪个codeigniter,从2.0.x开始,作为系统要求保留)

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

所以要回答解决问题的问题......

我不应该使用Index作为CodeIgniter中控制器类的名称吗?

我认为最好不要选择Index作为控制器名称,因为index()函数在codeigniter中有保留用途。这可能会导致问题,具体取决于您的PHP配置。

答案 2 :(得分:0)

这是使用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();
    }
}
}

viewall()有以下

$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);

Base控制器为整个应用程序执行所有库和帮助程序加载,这就是默认类中需要它的原因

基本上,由于我对CodeIgniter的简短理解,将默认操作作为索引是错误的。我通过使用打印$ this-> router-> fetch_method()的结果找到了这个。在我的索引类的construct()中。 CodeIgniter的默认操作是索引,您只能在application / config / routes.php中设置默认控制器,而不是默认操作。

所以我的建议,永远不要使用index()作为默认操作,特别是如果你使用index作为默认控制器