58 votes

get_instance() dans Codeigniter: Pourquoi l'attribuer à une variable?

Dans Codeigniter, get_instance() est disponible dans le monde entier la fonction qui retourne le Contrôleur de super-objet qui contient toutes les chargés de cours (il retourne le Contrôleur instance de classe). Je vais inclure le code source de courant:

get_instance() est définie en Codeigniter.php

// Load the base controller class
require BASEPATH.'core/Controller.php';

function &get_instance()
{
    return CI_Controller::get_instance();
}

Et CI_Controller est définie en Controller.php

class CI_Controller {

    private static $instance;

    /**
     * Constructor
     */
    public function __construct()
    {
        self::$instance =& $this;

        // Assign all the class objects that were instantiated by the
        // bootstrap file (CodeIgniter.php) to local class variables
        // so that CI can run as one big super object.
        foreach (is_loaded() as $var => $class)
        {
            $this->$var =& load_class($class);
        }

        $this->load =& load_class('Loader', 'core');

        $this->load->set_base_classes()->ci_autoloader();

        log_message('debug', "Controller Class Initialized");
    }

    public static function &get_instance()
    {
        return self::$instance;
    }
}

Voici comment il est recommandé pour être utilisé dans le guide de l'utilisateur pour créer des bibliothèques:

En utilisant CodeIgniter Ressources au sein de Votre Bibliothèque

Pour accéder à CodeIgniter natif de ressources au sein de votre utilisation de la bibliothèque de l' get_instance() fonction. Cette fonction renvoie le CodeIgniter super objet.

Normalement à partir de votre contrôleur, vous appeler tout de disponibles CodeIgniter fonctions à l'aide de l' $thisconstruire: $this->load->helper('url'); $this->load->library('session'); $this->config->item('base_url'); etc.

$this, cependant, ne fonctionne directement dans votre contrôleurs, votre modèles, ou de votre point de vue. Si vous souhaitez utiliser CodeIgniter les classes de à partir de vos propres classes personnalisées, vous pouvez le faire comme suit:

Tout d'abord, affectez la CodeIgniter objet à une variable:

$IC =& get_instance();

Une fois que vous avez assigné l'objet à une variable, vous devez utiliser variable au lieu de $this: $IC =& get_instance(); $IC->load->helper('url'); $IC->load->library('session'); $IC->config->item('base_url'); etc.

Note: Vous remarquerez que le ci-dessus get_instance() fonction est en cours passé par référence:

$IC =& get_instance();

C'est très important. L'assignation par référence vous permet d'utiliser le original CodeIgniter objet plutôt que d'en créer une copie.

Related posts: expliquer $IC =& get_instance(); / Codeigniter: Obtenir Instance

Donc, voici ma question:

Pourquoi le guide de l'utilisateur vous recommandons d'assigner get_instance() à une variable? Je suis assez certain que je comprends les conséquences de ne pas l'assignation par référence, mais pourquoi est-il recommandé d'affecter à une variable lors de l' get_instance()->load->model() fonctionne bien?

Je vois beaucoup d'défini par l'utilisateur ou un tiers des classes de CI que de céder à une propriété de l'objet:

class MY_Class {

    private $CI;

    function __construct()
    {
        $this->CI =& get_instance();
    }
    function my_func()
    {
        $this->CI->load->view('some_view');
    }
    function my_other_func()
    {
        $this->CI->load->model('some_model');
    }
}

Mauvais exemple, mais je le vois souvent. Pourquoi s'embêter avec cette méthode, au lieu de simplement en appelant get_instance() directement? Il semble comme affectation de l'ensemble de la commande de l'objet à une variable de classe ne serait pas une bonne idée, même si c'est une référence. Peut-être qu'il n'a pas d'importance.

Je veux écrire une fonction wrapper pour get_instance() il est donc plus facile à taper, et je n'ai pas à constamment l'affecter à une variable.

function CI()
{
    return get_instance();
}

Ou:

function CI()
{
    $CI =& get_instance();
    return $CI;
}

Ensuite, j'ai pu utiliser CI()->class->method() à partir de n'importe où, sans les tracas de l'affecter à une variable, il est très facile d'écrire et de comprendre ce qu'il fait, et peut résulter en une plus courte, plus le code élégant.

  • Est-il une raison de ne pas prendre cette approche?
  • Quelle est la différence entre les deux CI() fonctions ci-dessus?
  • Pourquoi est-il recommandé d'assigner get_instance() à une variable plutôt que de l'appeler directement?
  • Ce qui ne l' & en function &get_instance(){} moyenne où il est défini? Je sais un peu ce que les références sont pour, et je les utiliser lorsque cela est approprié, mais je n'ai jamais vu une fonction définie de cette façon. Si je dois écrire une fonction wrapper, dois-je l'utiliser?

Veuillez noter que ce n'est pas tant un style de question, mais une technique. Je veux savoir si il y a des problèmes, la performance ou autrement, avec l'aide de la méthode que je suggère.

EDIT: pour l'instant nous avons:

  • Le chaînage de méthode n'est pas disponible en php4, le fait de les affecter à une variable est une solution de contournement (même si c'est assez inutile comme Codeigniter a abandonné le support de php4)
  • Le mineur généraux de l'appel d'une fonction plus d'une fois pour retourner l'objet, plutôt que de l'appeler à la fois et de les assigner à une variable.

Autre chose, ou sont-ils les seuls problèmes potentiels?

22voto

Chris Schmitz Points 2978

Pour autant que je sais, c'est une question de commodité plus que tout. Les Chances sont que vous serez à l'aide de l'IC super objet de beaucoup de choses dans vos bibliothèques alors pourquoi ne pas l'affecter à une variable pour le rendre un peu plus facile de travailler avec?

Il ya quelques autres choses à considérer...

  1. Si vous mettez cette méthode dans un helper, cette méthode devient une dépendance pour toute la classe que vous l'utilisez. Ce ne serait pas une grosse affaire pour vous, mais si vous voulez partager des bibliothèques avec quelqu'un d'autre, ne peut pas être heureux au sujet de la dépendance, en particulier car il existe déjà un moyen standard de la manipulation dans l'IC de la communauté.
  2. Il y a un léger impact sur les performances, car vous vous appelez get_instance() chaque fois que vous utilisez l'assistant, plutôt que de stocker le résultat dans une variable.
  3. Puisque c'est une méthode d'assistance qui est censé vous faire gagner du temps, pour quelqu'un qui travaille principalement dans le noyau de la MVC fichiers de CI, l'établissement d'une aide comme cela prendrait plus de temps que de simplement définir une variable dans les quelques endroits que vous en avez besoin.

3voto

dev-null-dweller Points 19874

Pourquoi est-il recommandé d'assigner get_instance() à une variable plutôt que de l'appeler directement?

Plus probablement, il est recommandé de maintenir une compatibilité ascendante avec php4, où les objets n'étaient pas passés par référence par défaut, mais ont été clonés.

Est-il une raison de ne pas prendre cette approche?

Seulement si vous voulez que votre application de fonctionner sur de vieux php installations

3voto

Usman Points 6151

Le chaînage de méthode n'est pas pris en charge dans PHP4, CI a supprimé le support de PHP4 à très récemment (à partir de la version 2.0.0). Plus facile à écrire $CI que l'écriture get_instance() à chaque fois.

3voto

Ben Points 414

Il est nécessaire d'affecter par la référence parce que la valeur de CI_Controller::$instance est sujet à changement si une autre instance de la classe est créée. Le constructeur ré-attribue self::$instance chaque fois qu'il exécute.

En général, cela se sent comme un mauvais modèle de conception, et est absent de la propriété d'un singleton que les limites de la classe à un seul exemple, http://en.wikipedia.org/wiki/Singleton_pattern.

Il semble possible de type, CI_Controller::get_instance()->$className->$method(); qui semble plus saisissant que votre demande CI()->$className->$method.

En fin de compte, il serait judicieux d'exiger qu'une seule instance d' $instance peuvent être créés et la nécessité pour l'affectation par référence serait éliminé.

1voto

Repox Points 6921

Il pourrait être une combinaison de plusieurs choses, y compris l'ai déjà mentionné:

  • Rétro-compatibilité
  • Commodité
  • Guide De Style

De préférence, j'aime l'idée de cette "recommandation" comme étant une partie d'un guide de style. Peut-être pas le style de la guide de l'IC, mais tout de même.

Imaginez que tous les scripts tiers pour la CI met en œuvre cette recommandation, n'importe quel développeur serait en mesure de déterminer rapidement comment ces scripts sont conçus bien que ce juste une très petite partie du script.

Une autre chose que l'OMI est important, c'est la mécanique de la méthode de chaînage - CI()->class->method() ne semble pas intuitif pour moi, de savoir comment le reste de CI fonctionne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X