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.