web-dev-qa-db-fra.com

Comment charger un contrôleur d'un autre contrôleur dans codeigniter?

Je souhaite charger un contrôleur à partir d'une fonction d'un autre contrôleur car la bibliothèque que j'ai intégrée à mon projet ne veut pas la charger dans le contrôleur car je souhaite le garder propre et associé.

J'ai essayé d'utiliser des modules mais je devais quand même mettre le contrôleur dans l'URL comme 

http://example.com/maincontroller/function
http://example.com/othercontroller/function

J'ai le contrôleur par défaut pour que je puisse charger http://example.com/function alors comment puis-je accéder au contrôleur à partir d'une fonction de la commande main afin de ne pas mettre le contrôleur dans l'URL.

Je suis toujours disposé à utiliser HMVC si je peux charger la fonction de contrôleur à partir de la fonction de contrôleur principal. 

29
Luis Liz

Vous ne pouvez pas charger un contrôleur depuis un contrôleur dans CI - sauf si vous utilisez HMVC ou quelque chose du genre. 

Vous devriez penser à votre architecture un peu. Si vous devez appeler une méthode de contrôleur depuis un autre contrôleur, vous devez probablement extraire ce code en un utilitaire ou une bibliothèque et l'appeler à partir des deux contrôleurs.

METTRE À JOUR

Après avoir relu votre question, je me rends compte que votre objectif final n’est pas nécessairement le HMVC, mais la manipulation d’URI. Corrigez-moi si je me trompe, mais il semble que vous tentiez de créer des URL avec la première section correspondant au nom de la méthode et de laisser de côté le nom du contrôleur.

Si tel est le cas, vous obtiendrez une solution plus propre en obtenant créatif avec vos itinéraires

Pour un exemple vraiment basique, supposons que vous ayez deux contrôleurs, controller1 et controller2. Controller1 a une méthode method_1 - et controller2 a une méthode method_2.

Vous pouvez configurer des itinéraires comme ceci:

$route['method_1'] = "controller1/method_1";
$route['method_2'] = "controller2/method_2";

Ensuite, vous pouvez appeler la méthode 1 avec une URL telle que http://site.com/method_1 et la méthode 2 avec http://site.com/method_2.

Bien qu’il s’agisse d’un exemple très simple, codé en dur, mais il pourrait vous mener là où vous devez être si tout ce que vous avez à faire est de supprimer le contrôleur de l’URL.


Vous pouvez aussi aller avec remapper vos contrôleurs .

Dans la documentation: "Si votre contrôleur contient une fonction nommée _remap (), il sera toujours appelé quel que soit le contenu de votre URI.":

public function _remap($method)
{
    if ($method == 'some_method')
    {
        $this->$method();
    }
    else
    {
        $this->default_method();
    }
}
21
swatkins

oui vous pouvez (pour la version 2)

charger comme ça dans votre contrôleur

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

et appelez la méthode suivante:

$this->whathever->functioname();
42
Geomorillo

vous ne pouvez pas appeler directement une méthode de contrôleur depuis un autre contrôleur 

ma solution consiste à utiliser les héritages et à étendre votre contrôleur à partir du contrôleur de bibliothèque 

class Controller1 extends CI_Controller {

    public function index() {
        // some codes here
    }

    public function methodA(){
        // code here
    }
}

dans votre contrôleur, nous l'appelons Mycontoller il étendra Controller1

include_once (dirname(__FILE__) . "/controller1.php");

class Mycontroller extends Controller1 {

    public function __construct() {
        parent::__construct();
    }

    public function methodB(){
        // codes....
    }
}

et vous pouvez appeler methodA depuis mycontroller

http://example.com/mycontroller/methodA

http://example.com/mycontroller/methodB

cette solution a fonctionné pour moi

15
Moes

J'avais un problème similaire. Je voulais avoir deux contrôleurs:

homepage.php - page d'accueil publique

home.php - écran d'accueil une fois l'utilisateur connecté

et je voulais que les deux lisent de 'mydomain.com'

J'ai pu accomplir cela en définissant 'hompepage' comme contrôleur par défaut dans la configuration de mes routes et en ajoutant une fonction de remappage à homepage.php.

function _remap()
{
  if(user_is_logged_in())
  {
    require_once(APPPATH.'controllers/home.php'); 
    $oHome =  new Home();
    $oHome->index();
  }
  else
  {
    $this->index();
  }
}
8
Keith Ritter

Bien que les méthodes ci-dessus puissent fonctionner, voici une très bonne méthode.

Étendez le contrôleur principal avec un contrôleur MY, puis étendez ce contrôleur MY pour tous vos autres contrôleurs. Par exemple, vous pourriez avoir:

class MY_Controller extends CI_Controller {
    public function is_logged()
    {
        //Your code here
    }
public function logout()
    {
        //Your code here
    }
}

Ensuite, vos autres contrôleurs pourraient ensuite l’étendre comme suit:

class Another_Controller extends MY_Controller {
    public function show_home()
    {
         if (!$this->is_logged()) {
           return false;
         }
    }
public function logout()
    {
        $this->logout();
    }
}
1
Smith

J'avais un fichier de session pas trouvé d'erreur alors que j'essayais de différentes manières, finalement réussi comme ça. Fait la fonction en tant que statique (que je veux appeler dans un autre contrôleur), et appelé comme

require_once('Welcome.php');
Welcome::hello();
0
Rajesh

Créez un assistant en utilisant le code que j'ai créé ci-dessous et nommez-le controller_helper.php.

Chargement automatique de votre aide dans le fichier autoload.php sous config.

Depuis votre méthode, appelez controller('name') pour charger le contrôleur. 

Notez que name est le nom du fichier du contrôleur.

Cette méthode ajoutera '_controller' à votre contrôleur 'name'. Pour appeler une méthode dans le contrôleur, exécutez simplement $this->name_controller->method(); après avoir chargé le contrôleur, comme décrit ci-dessus.

<?php

if(!function_exists('controller'))
{
    function controller($name)
    {
        $filename = realpath(__dir__ . '/../controllers/'.$name.'.php');

        if(file_exists($filename))
        {
            require_once $filename;

            $class = ucfirst($name);

            if(class_exists($class))
            {
                $ci =& get_instance();

                if(!isset($ci->{$name.'_controller'}))
                {
                    $ci->{$name.'_controller'} = new $class();
                }
            }
        }
    }
}
?>
0
Taurai Muzopa

Пришел сюда, потому что мне нужно было создать функцию {{ render() }} в Twig, чтобы имитировать повенде пендей Рендеринг контроллеров из вида - это действительно круто для отображения независимых виджетов или материалов, которые можно перезагружать с помощью ajax.

Даже если вы не являетесь пользователем Brindille, вы все равно можете воспользоваться этим помощником и использовать его в своих представлениях для рендеринга контроллера, используя <?php echo twig_render('welcome/index', $param1, $param2, $_); ?>. То отобразит все, что выдает ваш контроллер.

Вот:

helpers/twig_helper.php

<?php

if (!function_exists('twig_render'))
{

    function twig_render()
    {
        $args = func_get_args();
        $route = array_shift($args);
        $controller = APPPATH . 'controllers/' . substr($route, 0, strrpos($route, '/'));

        $explode = explode('/', $route);
        if (count($explode) < 2)
        {
            show_error("twig_render: A twig route is made from format: path/to/controller/action.");
        }

        if (!is_file($controller . '.php'))
        {
            show_error("twig_render: Controller not found: {$controller}");
        }
        if (!is_readable($controller . '.php'))
        {
            show_error("twig_render: Controller not readable: {$controller}");
        }
        require_once($controller . '.php');

        $class = ucfirst(reset(array_slice($explode, count($explode) - 2, 1)));
        if (!class_exists($class))
        {
            show_error("twig_render: Controller file exists, but class not found inside: {$class}");
        }

        $object = new $class();
        if (!($object instanceof CI_Controller))
        {
            show_error("twig_render: Class {$class} is not an instance of CI_Controller");
        }

        $method = $explode[count($explode) - 1];
        if (!method_exists($object, $method))
        {
            show_error("twig_render: Controller method not found: {$method}");
        }

        if (!is_callable(array($object, $method)))
        {
            show_error("twig_render: Controller method not visible: {$method}");
        }

        call_user_func_array(array($object, $method), $args);

        $ci = &get_instance();
        return $ci->output->get_output();
    }

}

Специально для пользователей Twig (par Twig):

libraries/Twig.php

$this->_twig_env->addFunction('render', new Twig_Function_Function('twig_render'));

Usage

{{ render('welcome/index', param1, param2, ...) }}
0
Alain Tiemblo