CodeIgniter: контроллер нагрузки в контроллере
У меня есть контроллер home
с действием index
, который отображает набор признанных продуктов. Однако управление продуктами осуществляется с помощью контроллера product
, включая проприетарную модель и представления.
Как мне получить доступ к product
информации из действия index
в контроллере home
? Instancing product
не будет работать, поскольку класс не загружается во время выполнения, а CodeIgniter не предоставляет возможности динамически загружать контроллеры. Помещение класса product
в файл библиотеки также не работает.
Чтобы быть точным, мне нужны представления продукта (заполненные данными, обработанными контроллером product
), вставленными в индексный вид. Я запускаю CodeIgniter 2.0.2.
Ответы
Ответ 1
Если вам интересно, есть хорошо установленный пакет, который вы можете добавить в проект Codeigniter, который будет обрабатывать это:
https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/
Модульные расширения делает модульную структуру CodeIgniter PHP модульной. Модули представляют собой группы независимых компонентов, как правило, модель, контроллер и представление, расположенные в подкаталоге модулей приложений, которые могут быть удалены в другие приложения CodeIgniter.
ОК, поэтому большое изменение в том, что теперь вы будете использовать модульную структуру, но для меня это желательно. Я использовал CI около 3 лет и не могу представить жизнь без модульных расширений.
Теперь, здесь часть, которая имеет дело с непосредственно вызывающими контроллерами для рендеринга частичного просмотра:
// Using a Module as a view partial from within a view is as easy as writing:
<?php echo modules::run('module/controller/method', $param1, $params2); ?>
Вот и все. Обычно я использую это для загрузки небольших "виджетов", например:
- Календарь событий
- Список последних новостей
- Форматы подписки на рассылку новостей
- Опросы
Обычно я строю контроллер "виджета" для каждого модуля и использую его только для этой цели.
Ваш вопрос был также одним из моих первых вопросов, когда я начал с Codeigniter. Надеюсь, это поможет вам, хотя это может быть немного больше, чем вы искали. Я использую MX с тех пор и не оглядывался назад.
Обязательно прочитайте документы и просмотрите множество информации об этом пакете на форумах Codeigniter. Наслаждайтесь!
Ответ 2
Загрузите его так:
$this->load->library('../controllers/instructor');
и вызовите следующий метод:
$this->instructor->functioname()
Это работает для CodeIgniter 2.x.
Ответ 3
Просто добавьте больше информации о том, что сказал Заин Аббас:
Загрузите контроллер таким образом и используйте его, как он сказал:
$this->load->library('../controllers/instructor');
$this->instructor->functioname();
Или вы можете создать объект и использовать его следующим образом:
$this->load->library('../controllers/your_controller');
$obj = new $this->your_controller();
$obj->your_function();
Надеюсь, это поможет.
Ответ 4
В этом случае вы можете попробовать старую школьную php.
// insert at the beggining of home.php controller
require_once(dirname(__FILE__)."/product.php"); // the controller route.
Затем у вас будет что-то вроде:
Class Home extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->product = new Product();
...
}
...
// usage example
public function addProduct($data)
{
$this->product->add($data);
}
}
И тогда просто используйте методы контроллера, как вам нравится.
Ответ 5
Основываясь на ответе @Joaquin Astelarra, мне удалось написать этот маленький помощник с именем load_controller_helper.php:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if (!function_exists('load_controller'))
{
function load_controller($controller, $method = 'index')
{
require_once(FCPATH . APPPATH . 'controllers/' . $controller . '.php');
$controller = new $controller();
return $controller->$method();
}
}
Вы можете использовать/вызывать его следующим образом:
$this->load->helper('load_controller');
load_controller('homepage', 'not_found');
Примечание. Второй аргумент не является обязательным, так как он будет запускать метод с именем index, например CodeIgniter.
Теперь вы сможете загрузить контроллер внутри другого контроллера без использования HMVC.
Позднее Редактировать: Имейте в виду, что этот метод может иметь неожиданные результаты. Всегда проверяйте это!
Ответ 6
Здесь есть много хороших ответов для загрузки контроллеров внутри контроллеров, но для меня это противоречит шаблону mvc.
Меня беспокоит предложение:
(заполненный данными, обработанными контроллером продукта)
Модели для обработки и возврата данных. Если вы поместите эту логику в свою модель продукта, вы можете вызвать ее из любого контроллера, который вам нравится, не пытаясь извратить фреймворк.
Один раз из наиболее полезных цитат, которые я читал, было то, что контроллер был как "полицейский", чтобы маршрутизировать запросы и ответы между моделями и представлениями.
Ответ 7
С помощью следующего кода вы можете загрузить классы контроллера и выполнить методы.
Этот код был написан для codeigniter 2.1
Сначала добавьте новый файл MY_Loader.php
в каталог приложения/основного. Добавьте следующий код в только что созданный файл MY_Loader.php
:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
// written by AJ [email protected]
class MY_Loader extends CI_Loader
{
protected $_my_controller_paths = array();
protected $_my_controllers = array();
public function __construct()
{
parent::__construct();
$this->_my_controller_paths = array(APPPATH);
}
public function controller($controller, $name = '', $db_conn = FALSE)
{
if (is_array($controller))
{
foreach ($controller as $babe)
{
$this->controller($babe);
}
return;
}
if ($controller == '')
{
return;
}
$path = '';
// Is the controller in a sub-folder? If so, parse out the filename and path.
if (($last_slash = strrpos($controller, '/')) !== FALSE)
{
// The path is in front of the last slash
$path = substr($controller, 0, $last_slash + 1);
// And the controller name behind it
$controller = substr($controller, $last_slash + 1);
}
if ($name == '')
{
$name = $controller;
}
if (in_array($name, $this->_my_controllers, TRUE))
{
return;
}
$CI =& get_instance();
if (isset($CI->$name))
{
show_error('The controller name you are loading is the name of a resource that is already being used: '.$name);
}
$controller = strtolower($controller);
foreach ($this->_my_controller_paths as $mod_path)
{
if ( ! file_exists($mod_path.'controllers/'.$path.$controller.'.php'))
{
continue;
}
if ($db_conn !== FALSE AND ! class_exists('CI_DB'))
{
if ($db_conn === TRUE)
{
$db_conn = '';
}
$CI->load->database($db_conn, FALSE, TRUE);
}
if ( ! class_exists('CI_Controller'))
{
load_class('Controller', 'core');
}
require_once($mod_path.'controllers/'.$path.$controller.'.php');
$controller = ucfirst($controller);
$CI->$name = new $controller();
$this->_my_controllers[] = $name;
return;
}
// couldn't find the controller
show_error('Unable to locate the controller you have specified: '.$controller);
}
}
Теперь вы можете загрузить все контроллеры в каталог приложений/контроллеров.
например:
загрузите класс контроллера Invoice и выполните функцию test()
$this->load->controller('invoice','invoice_controller');
$this->invoice_controller->test();
или когда класс находится внутри каталога
$this->load->controller('/dir/invoice','invoice_controller');
$this->invoice_controller->test();
Он просто работает так же, как и загрузка модели
Ответ 8
Просто используйте
..............
self::index();
..............
Ответ 9
В соответствии с этим сообщением в блоге вы можете загрузить контроллер в другом контроллере в codeigniter.
http://www.techsirius.com/2013/01/load-controller-within-another.html
Прежде всего вам нужно расширить CI_Loader
<?php
class MY_Loader extends CI_Loader {
public function __construct() {
parent::__construct();
}
public function controller($file_name) {
$CI = & get_instance();
$file_path = APPPATH.'controllers/' . $file_name . '.php';
$object_name = $file_name;
$class_name = ucfirst($file_name);
if (file_exists($file_path)) {
require $file_path;
$CI->$object_name = new $class_name();
}
else {
show_error('Unable to load the requested controller class: ' . $class_name);
}
}
}
затем загрузите контроллер в другой контроллер.
Ответ 10
Я знаю, что это старо, но если кто-нибудь найдет его совсем недавно, я бы предложил создать отдельный файл класса в папке контроллеров. Передайте существующий объект контроллера в конструктор класса, а затем вы можете получить доступ к функциям из любого места и не противоречить настройке и обработке CI.