【问题标题】:Can't extend my Controller无法扩展我的控制器
【发布时间】:2026-02-05 07:10:02
【问题描述】:

我正在尝试为我的 Controller 类编写扩展。问题是我似乎无法弄清楚如何..

我有以下名为 test 的类,其中有一个函数简单地返回 aaaa 并在同一个文件中,最后作为我的 Controller

class test extends Controller
    {
        function test()
            {
                parent::Controller();
            }

        function echoMe(){

            return 'aaaaaaaaaaaaaaaaa';
        }
    }

在我的Controller 类中,我有一个函数,它是客户主页的一般输出。我正在尝试从上面的扩展中调用函数echoMe,但我不断得到

调用未定义的方法Controller::echoMe()

这是客户端函数(对echoMe()的调用就在顶部):

function controller_client1($controlData = NULL)
    {
        echo $this -> echoMe();

        //as the client page is content from the xml, mmodel needs the page number
        $pageNumber = '';
        if(isset($_GET['number']))
            {
                $num = htmlentities($_GET['number']);
                if(ctype_digit($num) && $num >= 0)
                    {
                        $pageNumber = $num;
                    }
            }
        else{
            $pageNumber = 0;
        }
        //loading the page content
        $data = $this->model->model_loadXMLdata($pageNumber);


        if(!empty($controlData))
            {
                //check if there is any info in the control data sent
                foreach($controlData as $key => $value)
                    {
                        //add the info to the data array
                        $data[$key] = $value;
                    }
            }

        $this->load->load_clientHomePage($data);
    }

我知道这是一个非常简单的问题。我一直在尝试遵循 this 指南,但有些东西没有点击...

有人可以帮忙吗?如何从测试中调用函数echoMe()

我知道如何编写一个全新的类并调用它,但我正在尝试学习如何正确扩展并不断失败。

我的意思是在某处的 Controller 中调用“测试”吗?

【问题讨论】:

  • 请附上您拨打controller_client1()的代码。

标签: php codeigniter controller extend


【解决方案1】:

在 config.php 中设置要扩展的文件的前缀。所以它应该是 My_test,除非你改变了这个预设(如下所示)

/*
|--------------------------------------------------------------------------
| Class Extension Prefix
|--------------------------------------------------------------------------
|
| This item allows you to set the filename/classname prefix when extending
| native libraries.  For more information please see the user guide:
|
| http://codeigniter.com/user_guide/general/core_classes.html
| http://codeigniter.com/user_guide/general/creating_libraries.html
|
*/
$config['subclass_prefix'] = 'MY_';

确保您的控制器位于正确的文件夹中(codeigniter 2.1.0 中的应用程序/核心),那么您应该没有问题。希望有帮助

这是我扩展的控制器。该文件名为 My_Controller.php(我知道有创意)

<?php
class MY_Controller extends CI_Controller {

function __construct()
{
    parent::__construct();
//constructor code here
}

//Custom functions here
}

//sencond controller I extend in the same file
class MY_Admin extends CI_Controller {

function __construct()
{
//more custom stuff for admin stuff
}

//more custom functions for admin stuff
}

?>

你有没有看到我在同一个文件中有两个扩展控制器。 我的扩展代码如下所示:

<?php
class home extends MY_Controller
{

如果我想扩展管理员,只需将 My_Controller 替换为 My_Admin。

【讨论】:

  • 啊,我实际上并没有使用 Code Igniter 我正在编写自己的小型 MVC 框架。我还没有真正使用过 Code Igniter。以这种方式扩展我自己的控制器实际上是否有任何意义,或者继续创建一个新类是否同样简单有效?
【解决方案2】:

echoMe() 函数在test 类中定义,而不是在Controller 类中。当使用Controller 类的实例调用controller_client1 函数时,echoMe 不存在,因为它没有在Controller 类中定义。

实现这一点的最佳方法是在基类Controller 中创建空的echoMe 函数。这种方式多态性起作用。从test 类的实例调用controller_client1 函数时,将执行该类的方法。否则,将执行基类中的方法。

希望我没有错过问题的重点:)

【讨论】:

  • 不,我明白你的意思。这是合乎逻辑的,我不能从测试中调用任何东西,直到在控制器中的某个地方调用。我试图通过控制器的扩展来分离公共、成员和管理功能..但到目前为止失败得很惨。
  • 可以test 调用未在 Controller 中定义的方法,但前提是您有 test 类的实例,例如$testObject = new test(); $testObject-&gt;echoMe(); 这会起作用,但$controllerObject = new Controller(); $controllerObject-&gt;echoMe(); 这不会,除非echoMe()Controller 中定义。
【解决方案3】:

echo $this -&gt; echoMe(); 将失败,因为它是在子(扩展)类中创建的,而您在父类中调用它。这个问题有点难理解。

abstract class Controller{
    public function __construct(){

    }

    public function echoMe($str){
        echo $str;
    }

}

class test extends Controller{
    public function __construct(){
       parent::echoMe('aaaaaaaaaa');
    }
}

【讨论】:

    【解决方案4】:

    试试这个(一般的想法,不仅仅是 CodeIgniter):

    $test = new test();
    echo $test->echoMe();
    

    请记住,test 扩展了您的 Controller 类,而不是相反 - 所以您不能在 test 类/对象实例之外调用您的方法。

    此外,升级到新版本的 CodeIgniter 可能是个好主意 - 不过要注意新的父控制器名称。

    编辑

    好的,这应该足以让您入门 - 请注意,它是 PHP5,而不是 PHP4,因此构造函数称为 __construct 而不是类名:

    class Controller {
        public $mainvar; 
    
        function __construct() {
            $this->mainvar = '<br />';
        }
    
        function echoMe() {
            return 'aaaaaaaaaaaaaaaaa';
        }
    }
    
    class Test extends Controller {
        function __construct() {
            parent::__construct();
        }
    
        function echoMeAgain(){
            return 'bbb';
        }
    }
    
    $test = new Test();
    
    echo $test->echoMe();
    echo $test->mainvar;
    echo $test->echoMeAgain();
    

    【讨论】:

    • 我得到以下信息:Call to undefined method Controller::Controller() 尝试在主 Controller 类中的 client1 函数中调用 new test() 时
    • 就像我说的,你不能从旧控制器内部调用你的新控制器方法,反之亦然 - 例如,如果你的 Controller 有一个方法 echoMe,那么你可以从您的test extends Controller 控制器调用该方法,明白吗?
    • 嗨 Shomz,感谢您的回复。我完全理解为什么不能在父级中调用子级函数的逻辑,这很有意义。但是,如何将其应用于 MVC?例如,如果符合某些条件,我可能只希望使用名为“class Admin_Controller extends Controller”的类,但我希望 Admin_Controller 能够访问所有主要的控制器数据,例如 $this->model..etc或者这只是糟糕的逻辑,我应该更多地考虑像 OpenCart 这样的东西,其中几乎有两半,一个管理员和一个非管理员..?
    • 不客气,约翰。是的,你说的很有道理,这就是我的建议。你的原始代码显示了一些不同的东西——在这个例子中,它就像试图让Controller 获得对其子控制器的访问权限。这就是为什么我说你应该反过来做。您在最后一句中提到的两种方法都很好,它只取决于您需要什么 - 如果您期望相等的用法,那么减半可能是要走的路。但是,如果您在管理控制器中需要的东西不是很多,并且不会阻塞主控制器,那么就这样做。 :)
    【解决方案5】:

    我认为 Kosta 实际上已经回答了这个问题,但您身边可能存在一些误解。所以让我通过一些示例代码来扩展它:

    class Controller {
        public function run() {
            $this->echoMe();
        }
    }
    
    class test extends Controller {
        public function echoMe() {
            echo "works";
        }
    }
    
    // This does NOT work, because Controller::echoMe does not exist
    $controller = new Controller();
    $controller->run();
    
    // This DOES work, because $this will be instance of test, and
    // test::echoMe exists and is callable.
    $test = new Test();
    $test->run();
    

    “扩展”并不意味着实际的控制器类得到扩展。新类“test”只是从 Controller 类继承了每个未声明为“私有”的方法和属性。 Controller 类本身保持不变。

    【讨论】:

      最近更新 更多