После двух последних комментариев я выложу свой реальный код и, возможно, он поможет:
Вот контроллер посадки:
<?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
или это (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
Моя теория относительно того, почему я получаю эти ошибки, заключается в том, что экземпляр объекта отличается от экземпляра, который загружал модель и библиотеки. Что в этом странного, так это то, что массивы переносятся, а не объекты. Таким образом, в ядре Loader.php массива codeigniter $ _ci_models заполняется моделями, которые не загружены в классе Public_homepage
Также, что может вам помочь, это то, что с первого прохода через класс businessbuilder я могу загружать и использовать модули успешно, но когда вызывается Public_homepage, именно тогда все начинает давать сбой.
Что сбивает с толку то, что я пытаюсь выяснить 2 ошибки с одним вопросом, который, вероятно, является моей ошибкой. Вот описание того, когда я получаю ошибки:
Error1:
Когда я запускаю код как есть, я не могу вызвать свойство sites.
Error2:
Когда я меняю
call_user_func_array (массив (& $ CI, $ function), array_slice ($ RTR-> uri-> rsegments, 2));
в
eval ($ class. "->". $ function);
Я понимаю, что это действительно сбивает с толку, особенно когда я объясняю это, но если вам нужна дополнительная информация, пожалуйста, дайте мне знать. Также обратите внимание, что Public_homepage выглядит так, потому что я тестирую. Нет необходимости сбрасывать больше бесполезных строк, если ошибка может быть вызвана минимальным кодом.
Обновление
Прочитав некоторые ответы, я понял, что не объяснил код. Этот код делает то, что он позволяет мне хранить разные URL в базе данных, но все сохраненные там URL могут вызывать одну и ту же страницу, даже если они разные. Я предполагаю, что точным примером будет изменение пули на WordPress.
В результате получается, что класс businessbuilder настроен на прием ВСЕХ запросов к серверу. Когда он попадает в класс businessbuilder, он получает доступ к базе данных, выясняет, какой под URL вы используете, находит реальный контроллер, который ищет пользователь, и получает доступ к этому контроллеру.