Calligniter Call Controller from the controller

After the last two comments, I will rip out my real code and maybe this will help:

Here is the landing controller:

<?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; } } } } 

here is an example of a dynamic controller that will be called:

 <?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); } } 

Here is my model that I am using:

 <?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 } } 

The error I get is either this (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 

or this (error2):

 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 

My theory as to why I get these errors is that the instance of the object is different from the one that loaded the model and libraries. Something strange is that it is that arrays are portable, but not objects. Thus, in the core Loader.php of the codeigniter $ _ci_models array is populated with models that are not loaded into the Public_homepage class

In addition, what can help you is that from the first pass through the business builder class, I can successfully load and use modules, but when Public_homepage is called, that when something starts to fail.

What makes this confusing is that I'm trying to figure out 2 errors with one question, which is probably my mistake. Here is a description of when I get errors:

Error1:

When I run the code as is, I cannot name the sites property.

Error2:

When I change call_user_func_array (array (& $ CI, $ function), array_slice ($ RTR-> uri-> rsegments, 2)); in eval ($ class. "->". $ function);

I understand that this is really confusing, especially when I explain it, but if you need more information, please let me know. Also note that Public_homepage looks like this because I'm testing. There is no need to unload more unnecessary lines if the error can be produced with minimal code.

Update

After reading some answers, I realized that I did not explain the code. What this code does is that it allows you to store different URLs inside the database, but all the URLs stored there can call the same page, even if they are different. I think the exact example would be changing a bullet to wordpress.

What happens is that the business builder class is configured to accept ALL server requests. When he gets into the business builder class, he will access the database, find out which sub-url you are using, find the real controller that the user is looking for, and gain access to this controller.

+8
codeigniter controller
source share
3 answers

So, after many searches, I think I have a workaround. The problem is what I was thinking with the instance. After diving into the framework, I realized that it stores the instance as a static var, private static $ instance. I changed the constructor so as not to overwrite if this var was populated. In addition to this, since there were still some loading oddities, for some reason the objects would be marked as loaded, but actually they weren’t there, I had to add a new var to the controller protected by $ ci_instance. In the end, I changed the CI_Controller to look like this:

 <?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 */ 

The only problem so far is that I cannot do $ this-> load-> model ("some_model") ;. Instead, I should use $ this-> ci_instance-> load-> model ("some_model"); and everything will come from there. I don’t care about the extra var, but I don’t like it when you change the ready-made solutions, because it increases the complexity of the update.

I have now marked this as an answer because it is what I have chosen to use as my solution, but I am still open for a better solution than the one I use. The exact description of what needs to be solved is as follows:

Copy all loaded properties from one instance to another. Basically, if possible, merging two copies.

If someone can answer this with a better solution than mine, preferably without changing the codeigniter core, I would gladly change my answer because I am not happy with my solution, because I do not know what effects I can meet later in development time.

+6
source share

In your /autoload.php application, specify codeigniter to load the database class.

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

That should be all you need to solve your problem.

+1
source share

if u uses HMVC only with

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

All Articles