2009-07-18 6 views
6

Je suis en train de créer un système de blog, que j'espère transformer en un CMS complet à l'avenir.Comment éviter d'utiliser des objets globaux PHP?

Il existe deux classes/objets qui seraient utiles pour avoir un accès global à (la connexion à la base de données mysqli et une classe personnalisée qui vérifie si un utilisateur est connecté).

Je cherche un moyen de le faire sans utiliser d'objets globaux, et si possible, ne pas passer les objets à chaque fonction chaque fois qu'ils sont appelés.

Répondre

13

Vous pouvez rendre les objets statiques, alors vous avez accès à eux n'importe où. Exemple:

myClass::myFunction(); 

Cela fonctionnera n'importe où dans le script. Cependant, vous pouvez vouloir lire des classes statiques, et éventuellement utiliser une classe Singleton pour créer une classe régulière à l'intérieur d'un objet statique qui peut être utilisé n'importe où.

élargi

Je pense que ce que vous essayez de faire est très semblable à ce que je fais avec ma classe de DB.

class myClass 
{ 
    static $class = false; 
    static function get_connection() 
    { 
     if(self::$class == false) 
     { 
      self::$class = new myClass; 
     } 
     return self::$class; 
    } 
    // Then create regular class functions. 
} 

Ce qui se passe est une fois que vous obtenez la connexion, en utilisant l'objet $ = myClass :: get_connection(), vous serez en mesure de faire quoi que ce soit fonction régulièrement.

$object = myClass::get_connection(); 
$object->runClass(); 

Expanded

Une fois que vous faire des déclarations statiques, il vous suffit d'appeler get_connection et affecter la valeur de retour à une variable. Ensuite, le reste des fonctions peut avoir le même comportement qu'une classe que vous avez appelée avec $ class = new myClass (parce que c'est ce que nous avons fait). Tout ce que vous faites est de stocker la variable de classe dans une classe statique.

class myClass 
{ 
    static $class = false; 
    static function get_connection() 
    { 
     if(self::$class == false) 
     { 
      self::$class = new myClass; 
     } 
     return self::$class; 
    } 
    // Then create regular class functions. 
    public function is_logged_in() 
    { 
     // This will work 
     $this->test = "Hi"; 
     echo $this->test; 
    } 
} 

$object = myClass::get_connection(); 
$object->is_logged_in(); 
+0

Salut, merci pour votre réponse, est-il possible de sauvegarder des variables dans des classes statiques. c'est-à-dire la fonction d'appel pour vérifier si l'utilisateur est connecté, puis accéder à cette variable plusieurs fois plus tard dans la page? –

+2

Oui, pour une classe statique, faites la même chose que j'ai faite pour déclarer la variable $ class. La seule chose est que vous devez déclarer toutes les variables que vous utilisez. –

+1

Mais, le code que je vous ai donné vous permet d'utiliser n'importe quelle classe régulière, eh bien, régulièrement. La partie statique vous donne simplement la classe, au lieu de la globaliser. Je vais modifier pour montrer un peu plus. –

1

Eh bien, si vous avez déjà un objet par lequel vous faites référence au système de blog, vous pouvez composer ces objets dans ce, afin qu'ils soient $blog->db() et $blog->auth() ou autre.

+0

Je pourrais, mais les objets auront également besoin d'accéder à l'extérieur de la classe de blog. –

8

Vous pouvez transmettre les objets actuellement globaux dans le constructeur.

<?php 
    class Foo { 
    protected $m_db; 
    function __construct($a_db) { 
     $this->m_db = $a_db; 
    } 
    } 
?> 
3

J'ai récemment réorganisé mon framework en préparation de la deuxième version du CMS de notre société. I undid une énorme quantité de choses que j'ai fait statique afin de les remplacer par des objets normaux. Ce faisant, j'ai créé une énorme quantité de flexibilité qui dépendait de moi pour passer à travers et pirater les fichiers de base. Je n'utilise maintenant que des constructions statiques lorsque la seule alternative est les fonctions globales, qui ne sont liées qu'à des fonctionnalités de base de bas niveau.

Je vais montrer quelques lignes de mon fichier bootstrap.php (toutes mes demandes sont envoyées via ce fichier, mais vous pouvez obtenir le même résultat en l'incluant en haut de chaque fichier) pour vous montrer ce que je veux dire. C'est une version assez lourde de ce que vous utiliseriez probablement dans votre situation, mais j'espère que l'idée est utile. (Tout est légèrement modifié.)

//bootstrap.php 

... 

// CONSTRUCT APPLICATION 

{  
    $Database = new Databases\Mysql(
     Constant::get('DATABASE_HOST'), 
     Constant::get('DATABASE_USER'), 
     Constant::get('DATABASE_PASSWORD'), 
     Constant::get('DATABASE_SCHEMA') 
    ); 

    $Registry  = new Collections\Registry; 
    $Loader  = new Loaders\Base; 
    $Debugger  = new Debuggers\Dummy; // Debuggers\Console to log debugging info to JavaScript console 

    $Application = new Applications\Base($Database, $Registry, $Loader, $Debugger); 
} 

... 

Comme vous pouvez le voir, j'ai toutes sortes d'options pour créer mon objet d'application, que je peux fourni comme argument dans le constructeur à d'autres objets pour leur donner accès à ces nécessités « globales ».

L'objet de base de données est explicite. L'objet de registre agit comme un conteneur pour l'objet I que vous souhaitez accéder ailleurs dans l'application. Le chargeur agit comme un utilitaire pour charger d'autres ressources comme des fichiers modèles. Et le débogueur est là pour gérer la sortie de débogage.

Je peux, par exemple, changer la classe de base de données que j'instancie et, voila j'ai une connexion à une base de données SQLite. Je peux changer la classe du débogueur (comme indiqué) et maintenant toutes mes informations de débogage seront enregistrées sur ma console JavaScript.

Bon, revenons maintenant au problème. Comment donnez-vous d'autres objets à tout cela? Vous le passez simplement dans un argument au constructeur. Non seulement cela, mais mon routeur (ou n'importe quel objet que je construis avec) est plus flexible aussi. Maintenant, je peux simplement instancier mon objet d'application différemment, et mon routeur se comportera différemment en conséquence.

Questions connexes