CodeIgniter: загрузка контроллера внутри контроллера - PullRequest
44 голосов
/ 23 мая 2011

У меня есть контроллер home с действием index, которое отображает набор рекомендуемых продуктов. Однако продукты управляются через контроллер product, включая проприетарную модель и представления.

Как получить доступ к product информации из действия index в контроллере home? Instancing product не будет работать, так как класс не загружается во время выполнения, а CodeIgniter не предоставляет способ динамической загрузки контроллеров. Помещение класса product в библиотечный файл тоже не работает.

Если быть точным, мне нужно, чтобы представления продуктов (заполненные данными, обработанными контроллером product) были вставлены в индексное представление. Я использую CodeIgniter 2.0.2.

Ответы [ 10 ]

63 голосов
/ 04 января 2013

Загрузите его вот так

$this->load->library('../controllers/instructor');

и вызовите следующий метод:

$this->instructor->functioname()

Это работает для CodeIgniter 2.x .

30 голосов
/ 23 мая 2011

Если вам интересно, есть хорошо зарекомендовавший себя пакет, который вы можете добавить в свой проект Codeigniter, который будет обрабатывать это:

https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/

Модульные расширения делает PHP-каркас CodeIgniter модульным.Модули - это группы независимых компонентов, обычно модели, контроллера и вида, расположенные в подкаталоге модулей приложения, которые можно поместить в другие приложения 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.Наслаждайтесь!

8 голосов
/ 12 июня 2013

Просто чтобы добавить больше информации к тому, что сказал Зейн Аббас:

Загрузите контроллер таким образом и используйте его так, как он сказал:

$this->load->library('../controllers/instructor');

$this->instructor->functioname();

Или вы можете создать объект и использовать его следующим образом:

$this->load->library('../controllers/your_controller');

$obj = new $this->your_controller();

$obj->your_function();

Надеюсь, это поможет.

8 голосов
/ 02 декабря 2011

В этом случае вы можете попробовать старый 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);
 }
}

А потом просто используйте методы контроллера, как вам нравится.

6 голосов
/ 03 мая 2013

На основании ответа @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.

Позднее редактирование. Имейте в виду, что этот метод может привести к неожиданным результатам. Всегда проверяйте это!

1 голос
/ 24 июня 2015

Здесь дано много хороших ответов для загрузки контроллеров внутри контроллеров, но для меня это противоречит шаблону mvc.

Предложение, которое меня беспокоит:

(заполнено данными, обработанными контроллером продукта)

Модели предназначены для обработки и возврата данных. Если вы добавите эту логику в модель своего продукта, то сможете вызывать ее с любого контроллера, который вам не нужен, без необходимости пытаться извращать платформу.

Одна из самых полезных цитат, которые я прочитал, заключалась в том, что контроллер был похож на «гаишника», чтобы направлять запросы и ответы между моделями и представлениями.

0 голосов
/ 29 июня 2016

Я знаю, что это старая версия, но если кто-нибудь найдет ее совсем недавно, я бы предложил создать отдельный файл класса в папке контроллеров. Передайте существующий объект контроллера в конструктор класса, и затем вы сможете получить доступ к функциям из любого места, и это не будет конфликтовать с настройкой и обработкой CI.

0 голосов
/ 06 июня 2014

Согласно этому сообщению в блоге вы можете загрузить контроллер в другой контроллер в 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);
        }
    }
}

затем загрузите контроллер в другой контроллер.

0 голосов
/ 19 декабря 2013

Просто используйте

..............

self::index();

..............

0 голосов
/ 24 декабря 2012

С помощью следующего кода вы можете загрузить классы контроллера и выполнить методы.

Этот код был написан для codeigniter 2.1

Сначала добавьте новый файл 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();

Это просто работаеттак же, как загрузка модели

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...