【问题标题】:Codeigniter Call Controller From ControllerCodeigniter 从控制器调用控制器
【发布时间】:2011-06-29 09:37:31
【问题描述】:

在最后两个 cmets 之后,我将转储我的真实代码,也许它会有所帮助:

这里是登陆控制器:

 <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Businessbuilder extends CI_Controller {

    function __construct()
    {
        parent::__construct();
    }
    function index()
    {
        $RTR = $GLOBALS["RTR"];


        // import the necessary libraries
        $this->load->model("site_pages");

        $RTR = $GLOBALS["RTR"];

        // get the current site
        $site = current_site();

        // get the requesting url
        $class = $RTR->uri->rsegments[1];
        $function = $RTR->uri->rsegments[2];

        // get the current function and class
        $current_method = explode("::", __METHOD__);

        // get the real class name that is going to be called
        $site_page = $this->site_pages->get(array("display_name"=>$class, "id"=>$site->id));
        $site_page = $site_page->result();
        if(count($site_page) == 1)
        {
            $site_page = $site_page[0];

            // set the class name to be called
            $class = $site_page->class_name;
        }

        // only execute if the requested url is not the current url
        if(!(strtolower($class) == strtolower($current_method[0]) && strtolower($function) == strtolower($current_method[1])))
        {
            if(!file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$class.EXT))
            {
                show_404($RTR->fetch_directory().$class);
                exit;
            }

            // include the required file. I use require once incase it is a file that I've already included
            require_once(APPPATH.'controllers/'.$RTR->fetch_directory().$class.EXT);

            // create an instance of the class
            $CI = new $class();

            if(method_exists($CI, $function))
                // call the method
                call_user_func_array(array(&$CI, $function), array_slice($RTR->uri->rsegments, 2));
            else
            {
                show_404($RTR->fetch_directory().$class);
                exit;
            }
        }
    }
}

这是一个将被调用的动态控制器的示例:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Public_homepage extends CI_Controller {

    function __construct()
    {
        parent::__construct();
    }

    function index()
    {
        echo "<br /><br /><br />";
        $this->load->model("sites");

        $style = $this->sites->get(array("id"=>1)); // fail here, sites not defined
        //print_r($style);
        exit;


        $view_params = array();
        $view_params["site_id"] = $this->site_id;

        $this->load->view('public_homepage', $view_params);
    }
}

这是我正在使用的模型:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Sites extends CI_Model
{
    function __construct()
    {
        parent::__construct();
    }

    function get($search = array())
    {
        return $this->db->query("SELECT * FROM sites"); // failure on this line, db undefined
        }
}

我得到的错误是这个(error1):

A PHP Error was encountered

Severity: Notice

Message: Undefined property: Public_homepage::$sites

Filename: controllers/public_homepage.php

Line Number: 15
Fatal error: Call to a member function get() on a non-object in /var/www/businessbuilderapp.com/public_html/application/controllers/public_homepage.php on line 15

或者这个(错误2):

A PHP Error was encountered

Severity: Notice

Message: Undefined property: Businessbuilder::$db

Filename: core/Model.php

Line Number: 50
Fatal error: Call to a member function query() on a non-object in /var/www/businessbuilderapp.com/public_html/application/models/bba_model.php on line 25 

我为什么会收到这些错误的理论是因为对象的实例与加载模型和库的实例不同。奇怪的是,数组被继承,而不是对象。所以在 codeigniter 数组 $_ci_models 的核心 Loader.php 中填充了 Public_homepage 类中未加载的模型

另外可能对您有所帮助的是,从第一次通过 businessbuilder 类开始,我就能够成功加载和使用模块,但是当调用 Public_homepage 时,事情就开始失败了。

让这令人困惑的是,我试图用一个问题找出 2 个错误,这可能是我的错误。以下是我收到错误时的描述:

错误1:

当我按原样运行代码时,我无法调用站点属性。

错误2:

当我改变 call_user_func_array(array(&$CI, $function), array_slice($RTR->uri->rsegments, 2)); 到 eval($class . "->" . $function);

我知道这确实令人困惑,尤其是在我解释时,但如果您需要更多信息,请告诉我。另请注意,Public_homepage 看起来像这样,因为我正在测试。如果可以用最少的代码产生错误,则无需转储更多无用的行。

更新

看了一些答案后,我意识到我没有解释代码。这段代码的作用是它允许我在数据库中存储不同的 url,但是存储在那里的所有 url 都可以调用同一个页面,即使它们不同。我想一个确切的例子是改变 wordpress 上的 slug。

发生的情况是 businessbuilder 类被设置为接受对服务器的所有请求。当它点击 businessbuilder 类时,它将访问数据库,找出您正在使用的子 url,找到用户正在寻找的真实控制器,然后访问该控制器。

【问题讨论】:

  • 在 index 方法中调用 $this->t() 还不够吗?
  • 非常混乱的描述,你到处都是。请发布您的确切错误消息,“最初我有类似的东西”代码是什么?你到底在做什么?当您将 $class 预先转换为对象时,如何将其与 append 函数一起使用?这里真的不清楚..
  • 是的,但这只是一个例子。在真正的程序中,它完全是一个不同的类。它类似于动态创建类实例的第二段代码。
  • ... 什么是 $this-&gt;authenticate=false;$authenticate 变量在哪里?你是如何铸造一个“控制器”的?我认为您对自己正在做的事情感到困惑...请用此代码解释您的意图,因为它非常不正确。
  • 那是旧代码。 $this->authenticate 被添加到基本控制器文件中,因为它正在构造函数中进行一些身份验证。

标签: codeigniter controller


【解决方案1】:

所以经过大量搜索,我想我有一个解决方法。问题是我对实例的想法。在深入研究框架后,我意识到它将实例存储为静态变量、私有静态 $instance。如果已填充该 var,我将构造函数修改为不覆盖。最重要的是,由于加载过程中仍然存在一些奇怪的问题,出于某种原因,对象会被标记为已加载,但实际上并非如此,我不得不向控制器添加一个新的 var,受保护的 $ci_instance。最后,我将 CI_Controller 修改为如下所示:

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * CodeIgniter
 *
 * An open source application development framework for PHP 5.1.6 or newer
 *
 * @package     CodeIgniter
 * @author      ExpressionEngine Dev Team
 * @copyright   Copyright (c) 2008 - 2011, EllisLab, Inc.
 * @license     http://codeigniter.com/user_guide/license.html
 * @link        http://codeigniter.com
 * @since       Version 1.0
 * @filesource
 */

// ------------------------------------------------------------------------

/**
 * CodeIgniter Application Controller Class
 *
 * This class object is the super class that every library in
 * CodeIgniter will be assigned to.
 *
 * @package     CodeIgniter
 * @subpackage  Libraries
 * @category    Libraries
 * @author      ExpressionEngine Dev Team
 * @link        http://codeigniter.com/user_guide/general/controllers.html
 */
class CI_Controller {

    private static $instance;
    protected $ci_instance; // line added

    /**
     * Constructor
     */
    public function __construct()
    {

        if(self::$instance == null) // line added
            self::$instance =& $this;

        $this->ci_instance =& get_instance(); // line added

        // Assign all the class objects that were instantiated by the
        // bootstrap file (CodeIgniter.php) to local class variables
        // so that CI can run as one big super object.
        foreach (is_loaded() as $var => $class)
        {
            $this->$var =& load_class($class);
        }

        $this->load =& load_class('Loader', 'core');

        $this->load->_base_classes =& is_loaded();

        $this->load->_ci_autoloader();

        log_message('debug', "Controller Class Initialized");
    }

    public static function &get_instance()
    {
        return self::$instance;
    }
}
// END Controller class

/* End of file Controller.php */
/* Location: ./system/core/Controller.php */

到目前为止,唯一的问题是我无法执行 $this->load->model("some_model");。相反,我必须使用 $this->ci_instance->load->model("some_model");一切都将从那里开始。我并不真正关心额外的 var,但我不喜欢修改开箱即用的解决方案,因为它增加了升级的复杂性。

现在我已将此标记为答案,因为它是“我”选择用作我的解决方案的解决方案,但我仍然愿意接受比我正在使用的解决方案更好的解决方案。需要解决的问题的具体描述如下:

将所有加载的属性从一个实例复制到另一个实例。如果可能的话,基本上做两个实例的合并。

如果有人可以用比我更好的解决方案来回答这个问题,最好不修改 codeigniter 核心,我很乐意改变我的答案,因为我对我的解决方案不满意,因为我不知道以后会遇到什么影响在开发过程中。

【讨论】:

【解决方案2】:

在你的 application/autoload.php 中设置 codeigniter 来加载数据库类。

$autoload['libraries'] = array('database', 'otherlibrary', 'otherlibrary2');

这一定是您解决问题所需要的全部。

【讨论】:

    【解决方案3】:

    如果你使用 HMVC 只是使用

    Class Models extends MX_Loader{
    
       function getUser($username){
           $sql="SELECT
                       *
                  FROM
                       user
                  WHERE username = ? "
           return $this->db->query($sql,array($username))->row();
       }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-11-14
      • 1970-01-01
      • 2017-05-06
      • 1970-01-01
      • 2016-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-23
      相关资源
      最近更新 更多