У меня есть home
контроллер с действием index
который отображает набор признанных продуктов. Однако продукты управляются с помощью контроллера product
включая проприетарную модель и виды.
Как получить доступ к информации о product
из действия index
в home
контроллере? product
Instancing не будет работать, поскольку класс не загружается во время выполнения, а CodeIgniter не предоставляет возможности динамически загружать контроллеры. Включение класса product
в файл библиотеки также не работает.
Чтобы быть точным, мне нужны представления продукта (заполненные данными, обработанными контроллером product
), вставленные в индексный вид. Я запускаю CodeIgniter 2.0.2.
Если вас это интересует, есть хорошо установленный пакет, который вы можете добавить в свой проект 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. Наслаждайтесь!
Загрузите его так
$this->load->library('../controllers/instructor');
и вызовите следующий метод:
$this->instructor->functioname()
Это работает для CodeIgniter 2.x.
Просто чтобы добавить дополнительную информацию к тому, что сказал Заин Аббас:
Загрузите контроллер таким образом и используйте его, как он сказал:
$this->load->library('../controllers/instructor'); $this->instructor->functioname();
Или вы можете создать объект и использовать его так:
$this->load->library('../controllers/your_controller'); $obj = new $this->your_controller(); $obj->your_function();
Надеюсь, это поможет.
В этом случае вы можете попробовать старую школу 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); } }
А затем просто используйте методы контроллера, как вам нравится.
Основываясь на ответе @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.
Позже Edit: Имейте в виду, что этот метод может иметь неожиданные результаты. Всегда проверяйте это!
Здесь есть много хороших ответов для загрузки контроллеров внутри контроллеров, но для меня это противоречит шаблону mvc.
Меня беспокоит предложение;
(заполненный данными, обработанными контроллером продукта)
Модели существуют для обработки и возврата данных. Если вы поместите эту логику в свою модель продукта, вы можете вызвать ее из любого контроллера, который вам нравится, не пытаясь извратить структуру.
Однажды из самых полезных цитат, которые я читал, было то, что контроллер был похож на «полицейский», чтобы маршрутизировать запросы и ответы между моделями и представлениями.
Просто используйте
…………..
self::index();
…………..
С помощью следующего кода вы можете загрузить классы контроллера и выполнить методы.
Этот код был написан для codeigniter 2.1
Сначала добавьте новый файл MY_Loader.php
в MY_Loader.php
приложения / основного. Добавьте следующий код в только что созданный файл MY_Loader.php
:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); // written by AJ sirderno@yahoo.com 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();
Он просто работает так же, как и загрузка модели
Согласно этому сообщению в блоге вы можете загрузить контроллер в другом контроллере в 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); } } }
затем контроллер нагрузки в другом контроллере.
Я знаю, что это старо, но если кто-нибудь найдет его совсем недавно, я бы предложил создать отдельный файл класса в папке контроллеров. Передайте существующий объект контроллера в конструктор класса, а затем вы можете получить доступ к функциям из любого места и не противоречить настройке и обработке CI.