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


Why are two controller methods being called in CodeIgniter?

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

应用程序/控制器/index . php

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

当我访问index/blah时,我看到indexblah打印。当我访问index/index时,我看到了indexindex。如果我将控制器重命名为其他东西(例如Foo),它不会有问题。这是显而易见的解决办法,但谁能告诉我为什么会发生这种情况?我应该将此作为bug报告给CodeIgniter吗?

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

为了进一步澄清问题是什么,在PHP4中,构造函数是一个与class具有相同名称的函数…

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

现在是PHP5版本(现在是编码器,从2.0开始)。X,作为系统需求)

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

所以要回答这个问题,解决这个问题…

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

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

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

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

比较构造函数和析构函数Docs:

为了向后兼容,如果PHP 5找不到给定类的__construct()函数,它将根据类的名称搜索旧式构造函数。[highlight by me]

在你的情况下,你的控制器没有任何__construct()函数,但是有一个与类同名的函数:index。它在Codeigniter解析和加载然后实例化您的Index控制器的时刻被调用。

你可以通过在你的控制器中添加构造函数来解决这个问题:
class Index extends CI_Controller
{
    public function __construct() {}
    public function index()
    {
        echo "index";
    }
    public function blah()
    {
        echo "blah";
    }
}

此更改后,不会再发生。

我应该将此作为bug报告给CodeIgniter吗?

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

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

基本控制器为整个应用程序加载所有的库和助手,这就是为什么它被要求在默认类

基本上从我对CodeIgniter的简短理解来看,将默认动作作为索引是错误的。我通过打印$this->router->fetch_method()的结果发现了这一点;在索引类的construct()中。CodeIgniter的默认操作是index,你只能在application/config/routes.php中设置默认控制器,而不能设置默认操作。

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