IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

[POO] Exemple de classe un peu tordue


Sujet :

Langage PHP

  1. #1
    Futur Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 11
    Points : 5
    Points
    5
    Par défaut [POO] Exemple de classe un peu tordue
    Bonjour,

    Je me lance dans la POO. J'ai déjà de bonnes notions mais j'avoue que j'ai du mal à comprendre la logique d'élaboration d'une classe ainsi que des possibilités raccordées à d'autres classes.

    Pouvez vous m'expliquer 2 ou 3 points sur des exemples concrets. J'ai lu dans des bouquins tout ce qui concerne la syntaxe mais leur classe expérimentale avec des voitures ne me parle pas vraiment.

    Je souhaiterais élaborer une classe d'authentification par exemple.
    1- Comment réfléchit-on aux différents attributs et méthodes de la classe Authentification ? (lesquels choisir en gros)
    2- Quel chemin élaborer dans sa petite cervelle pour mener à bien la classe ?

    Je sais pas si c'est bien clair mais je vous remercie pour toute l'aide éventuelle que vous pourriez m'apporter

  2. #2
    Membre régulier Avatar de daajack
    Inscrit en
    Octobre 2007
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 97
    Points : 97
    Points
    97
    Par défaut
    Le principe de la POO c'est de concevoir son application comme un ensemble d'objets qui vont interagir entre eux.
    Il y'a des objets évidents comme des voitures ou des utilisateurs et d'autre moins, comme un contrôleur de modèle MVC qui représente un concept virtuel, chargé de rediriger l'utilisateur sur les "sous-objets" en effectuant des traitements récurrents à chaque appel de page.
    Puis il y'a aussi les "extend" ou héritage de classe, qui permettent de créer des classes de base desquels dériveront d'autres classes plus complexes.

    Une erreur que l'on voit souvent, ce sont des gens qui créer des classes, desquelles ils instancient un objet, puis appellent les méthodes indépendamment, de la même manière qu'ils appelleraient des fonctions. Une sorte de groupement de fonctions. Hors la force des objets, à mon avis, est qu'ils ont une "vie" et évoluent dans le déroulement du script en leur affectant différentes valeurs de propriétés qui affecteront les appels futurs des méthodes.

    C'est là que l'on voit les limites du PHP en tant que langage "non-persistant". A chaque nouvel appel de page, l'ensemble des objets sont réinitialisés et il faut les reconstruire. Il faut donc aborder l'utilisation des objets en PHP de manière différentes que dans d'autres langages "persistants" (ex. Java, JS). Les objets sont là pour donner au développeur un canevas, qui l'obligera à structurer son application, sans lui donner l'évolutivité de la POO. Les objets sont crées, puis évolué lors de la création de la page sans intervention de l'utilisateur, si ce n'est les arguments et variables de sessions récupérés.

    On dit que la programmation objet va à l'encontre du mode de réflexion classique que nous utilisons, il faut donc "réapprendre à penser", de manière objet.

    Je sais c'est très théorique, c'est un essai, et je reste ouvert à toute critique.

    Pour reprendre ton exemple, voilà comment je m'y prendrai :

    Déjà créons une classe Utilisateur, la base.
    Il faudra y mettre les propriétés propres à l'utilisateur, qui seront utiles pour la suite des opérations. Le nom, la catégorie, l'heure de connexion, l'ip etc...
    Viennent les méthodes, déjà login() et logout(), changeCategory() for example
    Pour chaque page/action tu peux créer une classe qui contiendra comme propriété notamment la catégorie requise, ainsi qu'une méthode grantAccess() qui autorisera (ou pas) l'accès à l'utilisateur. Cette objet sera appelé par le contrôleur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class Controler {
     
    }
     
    class Utilisateur {
      var nom;
      var role;
      var ip;
      var timeLogin;
     
      function __construct() {}
      function login() {}
      function logout() {}
      function changeRole() {}
    }
     
    class Action {
      var access;
     
      function checkAccess() {}
    }
    Après il y'a des classes de mapping de DB (ORM) qui transforment en objets les tables, et qui vont donc te permettre de gérer tes types de données avec des objets. Ainsi l'ajout d'un objets se fera en 2 étapes, d'abord en passant dans la méthode addVoiture de ton objet Action (récupération et contrôle des données), puis add() de ton objet Voiture (insertion dans la DB).

    Cette exemple démontre qu'il est important de structurer ton app avant d'écrire ta première ligne de code. Puisque tu devras définir qui gérera quoi, en évitant de donner les mêmes rôles à plusieurs classes, et le mot d'ordre reste le même que pour n'importe quel paradigme, éviter à tout prix la redondance et optimiser les modifications futures.

    Voili, j'espère avoir été clair... et pas trop chiant aussi

  3. #3
    mon_nom_est_personne
    Invité(e)
    Par défaut
    pour savoir que je doit mettre dans une classe d'abord faut definir a quel moment dans ton programme cette classe va intervenir. et pour ca y'a pas 36 solutions, la modelisation. perso je suis assez old school je fait encore ca en ordinogramme.
    par exemple ou se place une classe qui gere des authentification ?
    normalement le fleau de ton appli sera :
    - j'arrive dessus
    - j'arrive sur la page d'authentification
    - verifie que j'existe dans la db
    - si oui me permettre d'accedé au reste sinon rentre chez toi.

    Donc deja le truc cool tu sais que ta classe va se trouver entre un formulaire et une page.
    donc p-e si tu as une classe d'analyse de form, pensé a un prototype de type form_listener pour dire que tout roule comme dans du beure avec d'autre form.

    ensuite qu'est-ce qui va se passer dans cette classe
    - tu va verifier si la personne est deja logé ou pas
    si non :
    - tu recup login/pwd
    - tu verifie qu'une personne avec de tels attributs exit en db
    - si oui, par example tu cree une session sinon tu retourne faux.

    si oui :
    - retourne vrai

    sous cette forme c'est pas tres visible mais dans un diagramme tu vois les boite dobc tu compte et tu as t'es methode plus ou moins.

    une pour verifier si une personne est deja logé
    une verrifier un login et un pwd
    et comme les deux sont pas lier ou on pas de constant pas d'attribut.

  4. #4
    Membre régulier Avatar de daajack
    Inscrit en
    Octobre 2007
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 97
    Points : 97
    Points
    97
    Par défaut
    +1 pour mon_nom_est_personne

    Déjà son logo est trop cool, vive GITS.
    Et modéliser son app. est chaudement recommandé, p.ex. avec l'UML

  5. #5
    Futur Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Merci à vous deux pour vos explications

    C'est quand même pas mal chaud de situer l'affaire !!!
    Mais grace à vos prouesses j'ai quand même cerner quelques trucs... Auriez vous une idée d'une appli simple que je pourrais réaliser en tenant compte de vos conseils mais en essayant d'utiliser le maximum d'éléments (héritage, interface, abstraction, etc...) ?
    Et vous montrer mon boulot au fur et à mesure de son évolution (de la modélisation à la prog) pour que vous me corrigiez ?

    Encore merci pour votre aide et soutien...

  6. #6
    Membre régulier Avatar de daajack
    Inscrit en
    Octobre 2007
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 97
    Points : 97
    Points
    97
    Par défaut
    Par définition, une application simple nécessitera un minimum de techniques différentes.
    Ce n'est donc pas une bonne idée de vouloir utiliser le plus d'éléments possibles. Il vaut mieux réfléchir, à partir de ton application, aux éléments dont tu auras besoin et c'est l'usage que tu feras des ces méthodes qui t'aideront à comprendre leur rôle.

    Tu peux essayer de faire un système de gestion d'accès comme tu proposais pour commencer et nous poster le code quand tu auras un peu avancé, on te donnera notre avis... en tout cas j'essaierai

  7. #7
    Futur Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Ok merci encore pour tout

    Je poste mon code dès que je pense avoir fait quelque chose de potab'!

  8. #8
    Futur Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Bonjourà tous,

    Je voudrais être sur d'avoir compris le principe (après avoir relu vos posts plusieurs fois )

    Je reprends le système de daajack.

    En gros il faut donc créer une classe que l'on va appelée "controller" qui va être chargé de réguler, de paramétrer ou de contrôler les différents objets de notre système. Par exemple, si je créer un objet Utilisateur et que je veux utiliser dans une base de données, je dois tout d'abord réaliser une classe concernant l'environnement nécessaire à l'utilisateur mais aussi à d'éventuelles autres objets (je schématise en essayant d'aller à l'essentiel).

    Ensuite, je crée l'objet Utilisateur (classe) qui va définir notre utilisateur par le login, mot de passe, catégorie (administrateur ou membre), email, etc...

    Puis pour finir, une dernière classe pour creer les actions diverses pouvant être réaliser sur notre utilisateur : se loguer, supprimer, modifier, inserer dans la base, modifier le mot de passe.

    Je résume : Controleur -> Utilisateur -> Action
    Avec dans controleur :
    - Connexion à la base de donnée
    - Diverses définitions (mysql_fetch_assoc, mysql_insert_id, etc...)
    - Faire une blacklist de tous les termes inappropriés aux requêtes sql par exemple
    - etc...

    dans Utilisateur :
    - Définition des attributs
    - Utilisation dans un formulaire
    - Résultats après action
    - etc...

    et dans Action :
    - Les méthodes pouvant agir sur l'utilisateur : modification du login, suppression de l'utilisateur, ...
    - Gestion des erreurs du à une mauvaise saisie
    - Envoi de l'email (peut etre meme creer une classe a part entiere pour ca ?)
    - etc...

    Dites moi si ca colle ? ou si il faut penser autrement ?
    J'avoue que c'est la classe Utilisateur qui me pose le plus de mal dans la compréhension de ce qu'elle doit contenir

    Merci d'avance

  9. #9
    Membre régulier Avatar de daajack
    Inscrit en
    Octobre 2007
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 97
    Points : 97
    Points
    97
    Par défaut
    Ce n'est pas exactement ce à quoi je pensais.

    Déjà pour tout ce qui concerne le CRUD des objets, si tu utilises un ORM ce ne sera pas dans la classe utilisateur que tu trouveras tes méthodes pour éditer la BD mais dans des classes spécifiques à chaque table (ex. Voiture, Marque, ...).

    Concernant les classes action, l'idée c'est plutôt de définir une classe par page qui hérite de la classe Action, qui contiendra les méthodes de pré-traitements du CRUD.

    Le contrôleur lui dispatch les URL pour les différentes classes action, sécurise les données utilisateur ($_REQUEST) et charge les librairies communes p.ex.

    Si ça t'intéresses c'est l'idée générale des frameworks POO Symfony ou Pluf.

    Ce serait intéressant pour toi de les essayer et développer une petite application dessus, là t'en auras des classes un peu tordues

  10. #10
    Futur Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Bonjour,

    Voila mon premier né en terme de classe... J'ai choisi finalement de faire une classe d'upload de fichier car c'est un domaine que je maitrise bien
    Bon c'est une premiere donc elle doit etre tres loin d'etre irreprochable mais elle marche !!!

    Je souhaite vraiment entendre toutes les critiques en espérant que certaines soient bonnes

    Voici la classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    class Upload
    {
     
    	private $name;
    	private $tmpName;
    	private $ext;
    	private $size;
    	private $size_img;
     
    	public function __construct($fileName, $fileTmpName, $fileSize)
    	{
    		$this->name = basename($fileName);
    		$this->tmpName = $fileTmpName;
    		$this->size_img = $fileSize;		
    	}
     
    	public function upload($newDir)
    	{
    		if($this->load())
    		{
    			if($this->extension())
    			{
    				if($this->taille())
    				{
    					$this->name = strtr($this->name, 'ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ', 'AAAAAACEEEEIIIIOOOOOUUUUYaaaaaaceeeeiiiioooooouuuuyy'); 
    					$this->name = preg_replace('/([^.a-z0-9]+)/i', '-', $this->name);
     
    					if($this->copy($newDir))
    						return 'Le fichier est uploadé';
    					else 
    						return 'Problème lors de l\upload du fichier';			
    				} else {
    					return 'La taille du fichier n\'est pas supportée';
    				}
    			} else {
    				return 'L\'extension du fichier n\'est pas valide';
    			}
    		} else {
    			return 'Une erreur est survenu lors du chargement de la photo';
    		}
    	}
     
    	public function weight($poid)
    	{
    		$this->size = $poid;		
    	}
     
    	private function copy($dossier)
    	{
    		if(move_uploaded_file($this->tmpName, $dossier .'/'. $this->name))
    			return true;
    		else
    			return false;
    	}
     
    	private function load() 
    	{
    		return is_uploaded_file($this->tmpName);
    	}
     
    	private function extension()
    	{
    		$extensions = array('.gif', '.jpg', '.jpeg', '.JPG', '.png');
    		$this->ext = strrchr($this->name, '.');
     
    		if(in_array($this->ext, $extensions))
    			return true;
    		else
    			return false;			
    	}
     
     
    	private function taille()
    	{
    		$taille = filesize($this->tmpName);
    		if($taille > $this->size)
    			return false;
    		else
    			return true;
    	}
     
     
    }
    Puis pour l'utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    $max_size = 10000;
    if(isset($_FILES['fichier']))
    {
     
    	$newUpload = new Upload($_FILES['fichier']['name'], $_FILES['fichier']['tmp_name'], $_FILES['fichier']['size']);
    	$newTaille = $newUpload->weight($max_size);
    	$resultUpload = $newUpload->upload('upload');
    	echo $resultUpload;
     
    }
     
    ?>
    <form action="" method="post" enctype="multipart/form-data">
    	<input type="hidden" name="MAX_FILE_SIZE" />
        Fichier : <input type="file" name="fichier" />
        <input type="submit" name="submit" value="Envoyer" />
    </form>
    J'attends avec impatience vos remarques

  11. #11
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 021
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 021
    Points : 2 278
    Points
    2 278
    Par défaut
    Salut,
    personnellement je trouve ta classe pas mal. Si ce n'est quelques soucis de nommage de méthodes. Mise à part le mélange anglais/français ^^ il y a des conventions qu'il vaut mieux suivre. Une méthode comme weight($poid) s'appelle un setter ou mutateur et en général elle est préfixée par set (ex : setWeight()). On ne sait pas non plus ce que fait taille(), par contre si tu la nommes isValidSize() on sait tout de suite qu'elle retourne un bool, c'est plus explicite. Idem pour extension() => hasValidExtension() ou un truc du style.
    Il vaudrait mieux définir une méthode pour définir les extensions valides plutôt que de les mettre en dur dans la classe (ou plutôt les mettre en dur par défaut mais permettre de les modifier sans toucher à la classe).


    Sinon ça peut être intéressant de ne pas retourner directement ton texte d'erreur car tu peux avoir envie de l'afficher à un autre moment qu'à l'upload. Dans ce cas tu peux par exemple le stocker dans un tableau membre $errors à utiliser plus tard.

    Rien à voir avec la POO mais ta méthode load() est inutile car move_uploaded_file() inclus is_uploaded_file(). Pour tester le format d'image le test d'extension ne suffit pas, il faut tester le type de l'image avec getImazeSize() par exemple car on peut uploader un jpg sans extension, sous Mac par exemple ou pire uploader du code exécutable sous une extension d'image.
    Vive les roues en pierre

  12. #12
    Futur Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Merci à toi pour ces conseils !!!

    Peux tu me donnere un coupe de main pour :

    Il vaudrait mieux définir une méthode pour définir les extensions valides plutôt que de les mettre en dur dans la classe (ou plutôt les mettre en dur par défaut mais permettre de les modifier sans toucher à la classe).


    Sinon ça peut être intéressant de ne pas retourner directement ton texte d'erreur car tu peux avoir envie de l'afficher à un autre moment qu'à l'upload. Dans ce cas tu peux par exemple le stocker dans un tableau membre $errors à utiliser plus tard.
    Pour les erreurs :

    public $errors = array();
    puis
    $errors[] = 'L\'extension du fichier n\'est pas valide';
    Est ce ce genre de chose dont tu me parles?

    Et pour les extensions, je vois ce que tu veux dire mais je ne vois pas comment le coder !!!

  13. #13
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 021
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 021
    Points : 2 278
    Points
    2 278
    Par défaut
    Pour les extensions je pensais à un truc du style (si tu restes avec ton système d'extensions) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public function __construct($fileName, $fileTmpName, $fileSize)
    	{
    		$this->name = basename($fileName);
    		$this->tmpName = $fileTmpName;
    		$this->size_img = $fileSize;		
    		// Par défaut		
    		$this->valid_extensions = array('.gif', '.jpg', '.jpeg', '.JPG', '.png');
    	}
     
    public function setValidExtensions($extensions) {
    	$this->valid_extensions = $extensions;
    }

    Ca te permet de pouvoir modifier les extensions depuis l'extérieur de la classe.

    Pour les erreurs c'est bien à ça que je pensais mais pour cette classe c'est peut-être pas utile...
    Vive les roues en pierre

  14. #14
    Futur Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Ok c'est bien mieux comme ca en effet !!!

    Merci beaucoup en tout cas pour ton interet et ton aide à mon encontre ...

    Si d'autres remarques, je suis preneur

Discussions similaires

  1. [POO] Exemple de classe
    Par Invité dans le forum Langage
    Réponses: 6
    Dernier message: 27/04/2008, 00h33
  2. [POO] Ecrire une classe descendante
    Par GLDavid dans le forum Langage
    Réponses: 4
    Dernier message: 14/10/2005, 19h04
  3. Réponses: 2
    Dernier message: 09/10/2005, 15h35
  4. requette sql un peu tordue
    Par maxidoove dans le forum Langage SQL
    Réponses: 3
    Dernier message: 26/08/2005, 14h52
  5. Contraintes un peu tordu
    Par Jovial dans le forum SQL Procédural
    Réponses: 5
    Dernier message: 15/04/2004, 16h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo