wake-up-neo.com

CodeIgniter: Controller in Controller laden

Ich habe einen home-Controller mit einer index-Aktion, die eine Reihe von vorgestellten Produkten anzeigt. Die Produkte werden jedoch über einen product-Controller einschließlich eines proprietären Modells und Ansichten verwaltet.

Wie kann ich über die Aktion product im Controller index auf home-Informationen zugreifen? Die Instanzierung product funktioniert nicht, da die Klasse zur Laufzeit nicht geladen wird und CodeIgniter keine Möglichkeit bietet, Controller dynamisch zu laden. Das Einfügen der product-Klasse in eine Bibliotheksdatei funktioniert auch nicht wirklich.

Um genau zu sein, muss ich die Produktansichten (gefüllt mit Daten, die vom Controller product verarbeitet werden) in die Indexansicht einfügen. Ich verwende CodeIgniter 2.0.2.

43
Daniel

Wenn Sie interessiert sind, gibt es ein gut etabliertes Paket, das Sie zu Ihrem Codeigniter-Projekt hinzufügen können, das dies erledigt:

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

Modular Extensions macht das Framework CodeIgniter PHP modular. Module sind Gruppen unabhängiger Komponenten, normalerweise Modell, Controller und Ansicht, die in einem Unterverzeichnis für Anwendungsmodule angeordnet sind und in anderen CodeIgniter-Anwendungen abgelegt werden können.

OK, also ist die große Änderung, dass Sie jetzt eine modulare Struktur verwenden würden - aber für mich ist dies wünschenswert. Ich benutze CI seit ungefähr 3 Jahren und kann mir ein Leben ohne Modular Extensions nicht vorstellen.

Hier ist der Teil, der sich mit dem direkten Aufruf von Controllern für das Rendern von Ansichtsausschnitten befasst:

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

Das ist alles dazu. Ich verwende dies normalerweise zum Laden kleiner "Widgets" wie:

  • Veranstaltungskalender
  • Liste der neuesten Nachrichtenartikel
  • Newsletter-Anmeldeformulare
  • Umfragen

Normalerweise baue ich für jedes Modul einen "Widget" -Controller und verwende ihn nur für diesen Zweck.

Ihre Frage war auch eine meiner ersten Fragen, als ich mit Codeigniter anfing. Ich hoffe, das hilft dir, auch wenn es vielleicht ein bisschen mehr ist, als du gesucht hast. Ich benutze MX seitdem und habe nicht zurückgeschaut.

Lesen Sie die Dokumente und lesen Sie die zahlreichen Informationen zu diesem Paket in den Codeigniter-Foren. Genießen!

30
Wesley Murch

Laden Sie es so

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

und rufen Sie die folgende Methode auf:

$this->instructor->functioname()

Dies funktioniert für CodeIgniter 2.x .

63

Nur um weitere Informationen zu dem hinzuzufügen, was Zain Abbas sagte:

Laden Sie den Controller auf diese Weise und verwenden Sie ihn wie er sagte:

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

$this->instructor->functioname();

Oder Sie können ein Objekt erstellen und folgendermaßen verwenden:

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

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

$obj->your_function();

Hoffe das kann helfen.

8
Salvador P.

In diesen Fällen können Sie einige PHP-Versionen der alten Schule ausprobieren.

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

Dann haben Sie etwas wie:

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

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

Und dann verwenden Sie einfach die Methoden des Controllers, wie Sie möchten.

7

Basierend auf der Antwort von @Joaquin Astelarra habe ich es geschafft, diesen kleinen Helfer namens load_controller_helper.php zu schreiben:

<?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();
    }
}

Sie können es wie folgt verwenden/aufrufen:

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

Hinweis: Das zweite Argument ist nicht obligatorisch, da die Methode mit dem Namen index wie CodeIgniter ausgeführt wird.

Jetzt können Sie einen Controller in einen anderen Controller laden, ohne HMVC zu verwenden.

Später bearbeiten: Beachten Sie, dass diese Methode unerwartete Ergebnisse haben kann. Testen Sie es immer!

6
machineaddict

Es gibt viele gute Antworten zum Laden von Controllern innerhalb von Controllern. Dies widerspricht mir jedoch dem MVC-Muster.

Der Satz, der mich beunruhigt, ist:

(gefüllt mit vom Produktcontroller verarbeiteten Daten)  

Die Modelle dienen dazu, Daten zu verarbeiten und zurückzugeben. Wenn Sie diese Logik in Ihr Produktmodell integrieren, können Sie sie von einem beliebigen Controller aus aufrufen, ohne das Framework pervers zu machen.

Eines der hilfreichsten Zitate, die ich gelesen habe, war, dass der Controller wie der "Verkehrspolizist" war, um Anfragen und Antworten zwischen Modellen und Ansichten weiterzuleiten.

1
charliefortune

Mit dem folgenden Code können Sie die Controller-Klassen laden und die Methoden ausführen.

Dieser Code wurde für den Codeigniter 2.1 geschrieben

Fügen Sie zuerst eine neue Datei MY_Loader.php in Ihr Anwendungsverzeichnis ein. Fügen Sie der neu erstellten MY_Loader.php-Datei den folgenden Code hinzu:

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

}

Jetzt können Sie alle Steuerungen in Ihr Anwendungsverzeichnis/Steuerungsverzeichnis laden.

laden Sie die Controller-Klasse Invoice und führen Sie die Funktion test () aus.

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

$this->invoice_controller->test();

oder wenn sich die Klasse innerhalb eines Verzeichnisses befindet

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

$this->invoice_controller->test();

Es funktioniert genauso wie das Laden eines Modells

0
user1881928

Ich weiß, das ist alt, aber sollte es jemand neueren Datums finden, würde ich vorschlagen, eine separate Klassendatei im Controller-Ordner zu erstellen. Übergeben Sie das vorhandene Controller-Objekt an den Klassenkonstruktor, und Sie können von überall auf die Funktionen zugreifen. Es besteht kein Konflikt mit der Einrichtung und der Handhabung von CI.

0
Ukuser32

Benutz einfach

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

self::index();

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

0
Arkadij

Laut diesem Blogbeitrag können Sie den Controller in einen anderen Controller in Codeigniter laden.

http://www.techsirius.com/2013/01/load-controller-mit-einem anderen.html

Zunächst müssen Sie CI_Loader erweitern 

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

laden Sie dann den Controller in einen anderen Controller.

0
Webby