2012-10-09 2 views
7

J'ai travaillé sur le passage à la POO en PHP. J'ai lu des explications sur php.net, mais j'espérais pouvoir obtenir des réponses spécifiques ici.Comment structurer les classes en PHP

J'ai essayé de créer l'exemple suivant pour illustrer ma question. Dites que j'ai des classes "Base de données", "Produits" et "Utilisateurs", et que je veux afficher des produits si un utilisateur a accès. J'appelle donc la classe "Products" "showProducts()", qui à son tour crée une instance de la classe "User", qui crée une instance de l'objet "Database" et vérifie le niveau d'accès des utilisateurs.

Si l'utilisateur a accès, la fonction "showProducts()" crée une autre instance de l'objet "Database" et interroge la base de données.

class Database{ 

    public function query(){ 
     //runs query here 
    } 

    public function __construct() { 
     //sets up connection here 
    } 

} 

class User{ 

    public function checkAccess(){ 
     $db = new Database(); 
     $db->query(//pass in query to check access) 
     //does stuff, then returns true or false 
    } 

} 

class Products{ 

    public function showProducts(){ 

     $user = new User(); 

     if($user->checkAccess()) 
     $db = new Database(); 
     $db->query(//pass in query to get products) 
     } 

} 

J'espérais que quelqu'un pourrait illustrer comment le faire de la bonne façon. Je voudrais avoir une sorte de classe de contrôleur, qui crée un objet "Database", disponible pour toutes les classes qui ont besoin d'y accéder, sans avoir à créer plusieurs instances de l'objet "Database". Je voudrais la même chose avec la classe users, donc il y a un objet $ users auquel toutes les classes peuvent accéder, sans avoir à créer un nouvel objet chaque fois que j'ai besoin d'utiliser quelque chose dans la classe "User".

Je m'excuse si ma question n'est pas claire, et merci d'avance pour toute réponse !!

Merci à tous pour les réponses!

Répondre

11

Lorsque vous déplacez la procédure procédurale vers la programmation orientée objet, vous devez saisir plus de détails sur la façon de créer des classes. La POO n'écrit pas de cours, il s'agit de suivre les meilleures pratiques, les principes et les modèles de POO.

Vous ne devez pas instancier de nouveaux objets dans un autre, vous devez attribuer à l'objet Utilisateur, son objet Base de données dont dépend l'utilisateur, via le constructeur ou la méthode setter. C'est ce qu'on appelle l'injection de dépendance. L'objectif est de donner des objets à une classe qui en a besoin via la méthode constructeur ou setter. Et ils devraient être instanciés de l'extérieur de cette classe, il est donc plus facile de configurer la classe. Et lors de la construction d'une classe, vous voulez qu'il soit facile de voir quelles sont les dépendances de cette classe. Vous pouvez lire sur l'inversion du principe de contrôle ici: IoC

Alors votre code ressemblerait à ceci:

<?php 

// User object that depends on Database object, and expects it in constructor. 

class User 
{ 
    protected $database; 

    public function __construct($database) 
    { 
     $this->database = $database; 
    } 

    // -- SNIP -- 
} 

?> 

maintenant à utiliser cette classe d'utilisateurs que vous faites ceci:

<?php 

    $database = new Database($connParams); 
    $user = new User($database); 

?> 

Vous pouvez utilisez également Dependency Injection en utilisant des méthodes setter pour définir les dépendances, mais Il vous laisse google cela pour vous-même :)

C'est ce que vous pouvez lire sur Inversion of Contro ll, et sur les Conteneurs d'Injection de Dépendance et d'Injection de Dépendances, ce sont les meilleurs moyens de gérer les classes.

J'ai vu beaucoup de code PHP qui est "OOP" et en fait, ils n'utilisent que des classes comme espaces de noms de fonctionnalités :) Alors joute en apprendre davantage sur les principes et les modèles de POO.

Amusez-vous! :)

+0

Merci beaucoup pour la réponse!Donc, si j'avais une autre classe référencée sur la classe d'utilisateur, je passerais aussi l'objet utilisateur $ comme paramètre? – Ben

+0

Oui, vous pouvez! Vous pouvez passer autant de cours que vous le souhaitez. Vous pouvez passer un objet à travers le constructeur si l'objet a réellement besoin de cet objet pour fonctionner. Et vous pouvez le passer à travers la méthode setter si l'objet est optionnel. Une fois que vous avez des dépendances compliquées, alors vous pouvez penser à utiliser Conteneur d'Injection Dépendante où vous décririez les dépendances et Conteneur serait capable d'assembler l'objet des autres objets et de vous le renvoyer :) Vous pouvez en savoir plus sur Injection de Dépendance et Injection de Dépendance ici : http://fabien.potencier.org/article/12/do-you-need-a-dependency-injection-container – otporan

0

Pour faire un objet pour toute votre utilisation de code modèle Singleton:

class Database{ 
    private $db_descriptor; 

    private function __construct(){ 
     /* connect and other stuff */ 
    } 
    public static function getInstance(){ 
     static $instance; 
     if($instance === null){ 
      $instance = new self(); 
     } 
     return $instance; 
    } 
} 

Et vous pouvez utiliser la même technique avec les utilisateurs, je dis plus avec php 5.4, vous pouvez utiliser 1 trait pour singleton. Un dernier conseil: lorsque vous travaillez avec la base de données et d'autres choses lourdes, utilisez la technique lazy initialization. Lorsque vous améliorez vos compétences POO regardez Doctrine Project ils utilisent beaucoup ces techniques! Ne pas instancier des objets dans vos constructeurs ou d'autres méthodes.

+0

En fait, je recommanderais de regarder des exemples de cadres d'entreprise maintenant pour avoir une idée de la façon dont les choses sont faites. Vous n'aurez peut-être pas besoin d'utiliser immédiatement, mais ils vous donneront une bonne idée de la façon de structurer les choses. – prodigitalson

+0

Pouvez-vous conseiller un? Je n'ai pas travaillé avec eux avant. – kirugan

+1

Les frameworks Symfony2 et Zend2 sont les seuls frameworks qui valent la peine d'être regardés :) Je sais que j'aurai beaucoup de votes négatifs pour ça. Mais ces deux sont les meilleurs pour apprendre la bonne POO en PHP! – Limeni

2

Passez-les comme paramètre, de préférence à l'intérieur d'une classe différente connue sous le nom d'usine. Cela vous permettra de tester facilement votre code, mais aussi de créer facilement les objets.

De même, n'essayez pas d'utiliser des singletons. C'est la version orientée objet de "variables globales", et vous ne voulez pas utiliser de variables globales. Cela rend le test de votre code vraiment difficile, presque impossible.

Regardez cette vidéo http://www.youtube.com/watch?v=-FRm3VPhseI pour comprendre pourquoi il est mauvais d'utiliser des singletons. Surtout l'exemple CreditCard à 19h00 vaut la peine d'être regardé.

Si vous voulez vraiment le faire à la fine pointe de la technologie, jetez un coup d'œil au concept de «injection de dépendance». Essentiellement, le fait de passer des choses de l'extérieur dans une classe est tout le secret, mais il y a des cadres qui le font automatiquement pour vous, donc vous n'avez plus besoin d'écrire une usine. Ceux-ci sont appelés "Conteneur d'Injection de Dépendance" ou "DIC".

+0

Merci beaucoup! Googleing classe d'usine maintenant. Connaissez-vous de bons tutoriels généraux sur la mise en place de structures de classe pour les sites Web? Je commence à comprendre les principes, mais en ce qui concerne une mise en œuvre pratique, je suis encore un peu perdu. – Ben

+0

Tout d'abord, je vous recommande de regarder le chargement automatique. Il y a plusieurs systèmes pour faciliter cela, mais cela revient à organiser vos classes - une classe par fichier - dans une arborescence de répertoires, et à aligner les noms de classes pour que l'autochargeur, qui obtient seulement le nom de classe nécessaire comme paramètre, puisse construire le chemin et le nom de fichier dans lequel la classe est censée être. Jetez un coup d'œil au Zend Framework (1 ou 2) pour un exemple vivant. Vous pourriez avoir une idée de la façon dont les autres nomment leurs classes là aussi. – Sven

Questions connexes