CodeIgniter: Controlador de carga dentro del controlador


Tengo un controlador home con una acción index que muestra un conjunto de productos destacados. Sin embargo, los productos se administran a través de un controlador product que incluye un modelo y vistas propietarios.

¿Cómo puedo acceder a la información product desde la acción index en el controlador home? Instancing product no funcionará ya que la clase no se carga en tiempo de ejecución y CodeIgniter no proporciona una forma de cargar controladores dinámicamente. Poner la clase product en un archivo de biblioteca realmente no trabajo, tampoco.

Para ser preciso, necesito las vistas de producto (llenas de datos procesados por el controlador product) insertadas en la vista de índice. Estoy ejecutando CodeIgniter 2.0.2.

Author: Daniel, 2011-05-23

10 answers

Si estás interesado, hay un paquete bien establecido que puedes agregar a tu proyecto Codeigniter que manejará esto:

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

Modular Extensions hace que el framework PHP CodeIgniter sea modular. Los módulos son grupos de componentes independientes, típicamente modelo, controlador y vista, dispuestos en un subdirectorio de módulos de aplicación, que se pueden colocar en otros Aplicaciones CodeIgniter.

OK, así que el gran cambio es que ahora usarías una estructura modular, pero para mí esto es deseable. He usado CI durante aproximadamente 3 años, y no puedo imaginar la vida sin extensiones modulares.

Ahora, esta es la parte que trata de llamar directamente a los controladores para renderizar parciales de vista:

// 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); ?>

Eso es todo lo que hay. Normalmente uso esto para cargar pequeños "widgets" como:

  • Calendarios de eventos
  • Lista de últimas noticias artículos
  • Formularios de suscripción al boletín de noticias
  • Encuestas

Normalmente construyo un controlador "widget" para cada módulo y lo uso solo para este propósito.

Tu pregunta también fue una de mis primeras preguntas cuando empecé con Codeigniter. Espero que esto te ayude, a pesar de que puede ser un poco más de lo que estabas buscando. He estado usando MX desde entonces y no he mirado hacia atrás.

Asegúrese de leer los documentos y echa un vistazo a la multitud de información sobre este paquete en los foros de Codeigniter. ¡Que lo disfrutes!

 30
Author: Wesley Murch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-21 04:14:19

Cárgalo así

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

Y llame al siguiente método:

$this->instructor->functioname()

Esto funciona para CodeIgniter 2.x .

 64
Author: Zulqurnain abbas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-30 22:43:54

Solo para agregar más información a lo que dijo Zain Abbas:

Carga el controlador de esa manera, y úsalo como él dijo:

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

$this->instructor->functioname();

O puede crear un objeto y usarlo de esta manera:

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

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

$obj->your_function();

Espero que esto pueda ayudar.

 8
Author: Salvador P.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-12 08:47:58

En estos casos puedes probar php de la vieja escuela.

// insert at the beggining of home.php controller require_once(dirname(__FILE__)."/product.php"); // the controller route.

Entonces, tendrás algo como:

Class Home extends CI_Controller
{
 public function __construct()
 {
  parent::__construct();
  $this->product = new Product();
  ...
 }

 ...
 // usage example
 public function addProduct($data)
 {
  $this->product->add($data);
 }
}

Y luego simplemente usa los métodos del controlador como quieras.

 7
Author: Joaquin Astelarra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-01 20:51:53

Basado en la respuesta de @Joaquin Astelarra, he logrado escribir este pequeño ayudante llamado 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();
    }
}

Puedes usar / llamarlo así:

$this->load->helper('load_controller');
load_controller('homepage', 'not_found');

Nota: El segundo argumento no es obligatorio, ya que ejecutará el método llamado index, como lo haría CodeIgniter.

Ahora podrá cargar un controlador dentro de otro controlador sin usar HMVC.

Edición posterior: Tenga en cuenta que este método podría tener resultados inesperados. ¡Pruébalo siempre!

 6
Author: machineaddict,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-06 14:17:06

Hay muchas buenas respuestas dadas aquí para cargar controladores dentro de controladores, pero para mí, esto contradice el patrón mvc.

La frase que me preocupa es;

(rellenado con datos procesados por el controlador del producto)

Los modelos están ahí para procesar y devolver datos. Si pone esta lógica en su modelo de producto, entonces puede llamarlo desde cualquier controlador que desee sin tener que tratar de pervertir la marco.

Una de las citas más útiles que leí fue que el controlador era como el 'policía de tráfico', allí para enrutar solicitudes y respuestas entre modelos y vistas.

 1
Author: charliefortune,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-24 08:44:39

Solo use

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

self::index();

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

 0
Author: Arkadij,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-19 11:21:45

Con el siguiente código puede cargar las clases del controlador y ejecutar los métodos.

Este código fue escrito para codeigniter 2.1

Primero agregue un nuevo archivo MY_Loader.php en su directorio application/core. Agregue el siguiente código a su nuevo archivo 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);
    }

}

Ahora puede cargar todos los controladores en el directorio application/controllers. por ejemplo:

Cargue la factura de la clase del controlador y ejecute la función test()

$this->load->controller('invoice','invoice_controller');

$this->invoice_controller->test();

O cuando el la clase está dentro de un dir

$this->load->controller('/dir/invoice','invoice_controller');

$this->invoice_controller->test();

Funciona igual que cargar un modelo

 0
Author: user1881928,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-19 11:42:39

De acuerdo con esta entrada de blog, puede cargar el controlador dentro de otro controlador en codeigniter.

Http://www.techsirius.com/2013/01/load-controller-within-another.html

En primer lugar es necesario extender 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);
        }
    }
}

Luego cargue el controlador dentro de otro controlador.

 0
Author: Webby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-29 06:40:04

Sé que esto es antiguo, pero si alguien lo encuentra más recientemente, sugeriría crear un archivo de clase separado en la carpeta controllers. Pase el objeto controlador existente en el constructor de clase y luego puede acceder a las funciones desde cualquier lugar y no entra en conflicto con la configuración y el manejo de CI.

 0
Author: Ukuser32,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-29 14:18:34