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 :

Débutante en POO en php [PHP 5.3]


Sujet :

Langage PHP

  1. #1
    Membre régulier
    Femme Profil pro
    Développeur Web
    Inscrit en
    Février 2004
    Messages
    282
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2004
    Messages : 282
    Points : 103
    Points
    103
    Par défaut Débutante en POO en php
    Bonjour,

    Comme je commence une autoformation en Programmation orienté objet en PHP. J'ai commencé de créer ma premiere classe :
    Personnage.class.php
    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
    class Personnage
    {
        private $force;
        private $localisation;
        private $experience;
        private $degats; 
     
        function chargerClasse ($classe)
        {
            require $classe . '.class.php'; // On inclue la classe correspondante au paramètre passé
        }
     
        spl_autoload_register ('chargerClasse');
        // On enregistre la fonction en autoload pour qu'elle soit appelée dès qu'on instanciera une classe non déclarée
     
        $perso = new Personnage();
     
    }
    Une fois que j'executes le fichier, l'erreur suivant me sort :
    ( ! ) Parse error: syntax error, unexpected T_STRING, expecting T_FUNCTION in C:\wamp\www\POO\Personnage.class.php on line 13

    Merci de m'expliquer pourquoi.

  2. #2
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Salut

    Regarde ton code, tu fais en gros ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Toto {
        $truc = new Truc();
    }
    Or, une classe doit être constituée/structurée de méthodes de classe, et c'est dans ces méthodes que les traitements devront se faire (c'est toute la différence avec une fonction).

    Bien qu'au niveau de la syntaxe une méthode est déclarée par le mot function ce n'est tout de même pas une fonction, mais une méthode.
    Pour exemple, chargerClasse est une méthode de classe (une méthode de la classe Personnage).

    Il y a une autre erreur concernant l'appel à la fonction spl_autoload_register ('chargerClasse').
    Il te faut consulter systématiquement la doc de Php lorsque tu exploites une fonction où tu ne sais pas trop comment l'exploiter. Il y a des explications et bien souvent des exemples de codes.
    -> spl_autoload_register()

    Quand on passe juste une chaine (chargerClasse), ceci sous entendra que "chargerClasse" soit une fonction.
    Or, "chargerClasse" ici n'est pas une fonction mais une méthode de la classe "Personnage".

    spl_autoload_register() permet de faire référence à une méthode de classe, et permet d'ailleurs 2 façons pour ça.
    - Si la méthode de classe est statique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    spl_autoload_register ('Personnage::chargerClasse')
    - Et si la méthode de classe n'est pas statique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    spl_autoload_register (array('Personnage', 'chargerClasse'))
    (on passe un tableau : le 1er élément sera le nom de la classe, le 2ème le nom de la méthode).


    Un autre problème encore vient du concept.
    Tu prévois un système d'auto-chargement de classes dans la classe "Personnage" de même que son instanciation.
    Je ne pense pas que ce soit possible, cela devrait provoquer une erreur de double déclaration.

    Il te faudrait séparer certaines choses, car le principal but de faire de la POO, c'est de créer des classes où chacune d'entre elles aura une tâche à faire et ne fera que ça (et non des classe genre "fourre tout").

    L'auto-chargement de classe est une tâche à part, donc on créera une fonction ou mieux une classe autoload.
    L'exemple dans la doc est un bon début et répondra très certainement à ce que tu veux.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class ClassAutoloader {
            public function __construct() {
                spl_autoload_register(array($this, 'loader'));
            }
            private function loader($className) {
                echo 'Trying to load ', $className, ' via ', __METHOD__, "()\n";
                include $className . '.php';
            }
        }
    Ensuite, tu prévois une classe Personnage où son instanciation se faire à l'intérieur de celle ci.
    Même si cela est possible, j'ai plutôt idée que l'instanciation devrait se faire en dehors.
    Donc d'avoir une classe Personnage puis d'avoir une page (genre personne.php) où on exploitera cette classe.
    Exemple : (Une page personne.php accessible via une URL comme : http://www.domaine.com/personne.php)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <?php
    // Fichier : personne.php
     
    // On inclus la classe d'auto-chargement de classe
    require('autoload.php');
     
     
    $personne = new Personnage();

  3. #3
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Points : 16 372
    Points
    16 372
    Par défaut
    En dehors des considérations techniques exposées par RunCodePHP (avec justesse ) il ya les considérations de conception.
    Tu as une classe Personnage, qui correspond, je suppose, à un personnage de jeu vidéo. La classe serait un type de personnage. Est-ce que ce type de personnage rajoute des spécifications en fonction du type ? dans ce cas, il faudrait sans doute envisager de créer des classes héritant de Personnage.
    Par exemple : Personnage est la classe de base avec des attributs de force et d'expérience, et tu as un type Magicien qui est un Personnage avec les mêmes attributs force et expérience et un attribut "pouvoir magique". Ce qui donne quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     class Personnage
    {
        private $force;
        private $localisation;
        private $experience;
        private $degats; 
    }
    class Magicien extends Personnage 
    {
        private $magie;
    }

  4. #4
    Membre régulier
    Femme Profil pro
    Développeur Web
    Inscrit en
    Février 2004
    Messages
    282
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2004
    Messages : 282
    Points : 103
    Points
    103
    Par défaut
    Merci pour vos interventions, comme je l'ai dis il s'agit d'une autoformation et sur un autre site que j'ai trouvé ce tutoriel bien expliquer en plus avec un TP de pas à pas (avis personnel). Au départ je n'avais pas le probleme cad j'arrive à exécuter le code mais quand j'ai voulu refaire le TP c'est ici ou je me trouve avec l'erreur fatal. Ci-après une partie du document je ne sais pas si je peux vous donner le chemin exacte il s'agit d'un autre site :
    bla bla bla
    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
    <?php
        class Personnage
        {
            private $force;
            private $localisation;
            private $experience;
            private $degats;
     
            public function deplacer()
            {
     
            }
     
            public function frapper()
            {
     
            }
     
            public function gagnerExperience()
            {
                $this->experience++;
            }
     
        }
    ?>
    bla bla bla ...
    Créer et manipuler un objet:
    On va donc voir comment créer un objet, c'est-à-dire que l'on va utiliser notre classe (qui peut être comparée à une machine) afin qu'elle nous fournisse un objet. Pour créer un nouvel objet, vous devez faire précéder le nom de la classe à instancier du mot-clé new, comme ceci :

    Code : PHP - Sélectionner
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <?php
        $perso = new Personnage();
    ?>
    Ainsi, $perso sera un objet de type Personnage. On dit que l'on instancie la classe Personnage, qu'on crée une instance de la classe Personnage.


    Auto-chargement des classes

    Pour une question d'organisation, il vaut mieux créer un fichier par classe. Vous appelez votre fichier comme bon vous semble et vous placez votre classe dedans. Pour ma part, mes fichiers sont toujours appelés MaClasse.class.php.

    Si vous essayez de créer une instance de la classe alors que vous n'avez pas inclus le fichier déclarant la classe, une erreur fatale sera levée pour dire que vous instanciez une classe qui n'existe pas. Et c'est là qu'intervient l'auto-chargement des classes. Vous pouvez créer dans votre fichier principal (c'est-à-dire celui où vous créerez une instance de votre classe) une ou plusieurs fonction(s) qui tenteront de charger le fichier déclarant la classe. Dans la plupart des cas, une seule fonction suffit. Ces fonctions doivent accepter un paramètre, c'est le nom de la classe qu'on doit tenter de charger. Par exemple, voici une fonction qui aura pour rôle de charger les classes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <?php
        function chargerClasse ($classe)
        {
            require $classe . '.class.php'; // On inclue la classe correspondante au paramètre passé
        }
    ?>
    Essayons maintenant de créer un objet pour voir si il sera chargé automatiquement (je prends pour exemple la classe Personnage et prends en compte le fait qu'un fichier Personnage.class.php est créé).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <?php
        function chargerClasse ($classe)
        {
            require $classe . '.class.php'; // On inclue la classe correspondante au paramètre passé
        }
     
        $perso = new Personnage(); // Instanciation de la classe Personnage qui n'est pas déclarée dans ce fichier
    ?>
    Et là… Bam ! Erreur fatale ! La classe n'a pas été trouvée, elle n'a donc pas été chargée… Normal quand on y réfléchi ! PHP ne sait pas qu'il doit appeler cette fonction lorsqu'on essaye d'instancier une classe non déclarée. On va donc utiliser la fonction spl_autoload_register en spécifiant en premier paramètre le nom de la fonction à charger :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?php
        function chargerClasse ($classe)
        {
            require $classe . '.class.php'; // On inclue la classe correspondante au paramètre passé
        }
     
        spl_autoload_register ('chargerClasse'); // On enregistre la fonction en autoload pour qu'elle soit appelée dès qu'on instanciera une classe non déclarée
     
        $perso = new Personnage();
    ?>
    Et là, comme par magie, aucune erreur ne s'affiche ! Notre auto-chargement a donc bien fonctionné.

    Décortiquons ce qui s'est passé. En PHP, il y a ce qu'on appelle une pile d'autoloads. Cette pile contient une liste de fonctions. Chacune d'entre elles sera appelée automatiquement par PHP lorsque l'on essaye d'instancier une classe non déclarée. Nous avons donc ici ajouté notre fonction à la pile d'autoloads afin qu'elle soit appelée à chaque fois qu'on essaye d'instancier une classe non déclarée.

    Bien à vous.

  5. #5
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Au départ je n'avais pas le probleme cad j'arrive à exécuter le code mais quand j'ai voulu refaire le TP c'est ici ou je me trouve avec l'erreur fatal
    Ce qui est dit au dessus est correcte, c'est ton code qui ne va pas.

    Si je peux émettre un conseil.
    Vu que tu débute dans la POO, il serait mieux de mettre de coté l'auto-chargement de classe pour le moment, ça me semble un aspect qui est bon à apprendre bien plus tard.
    Il est bon de savoir comment charger ces classes de manière classique, c'est à dire en les incluant (require ou include) manuellement/explicitement.
    Le coté automatique de l'auto-chargement de classe peut être assez déroutant et rendre les chose confuses.

    Il est préférable de se concentrer d'abord sur la syntaxe propre ou particulière à l'Objet, c'est le BABA, sans cela c'est mission impossible.
    Puis après les mécanismes propre à l'Objet (visibilité, héritage, etc ...).
    Et enfin de la conception de ces Objets/Classes. C'est la partie la plus délicate, mais très certainement la plus intéressante (à condition de connaitre les étape 1 et 2).
    Le plus important est là.


    Puis c'est bien de se référer à des tutos, mais de mon coté j'ai toujours privilégié un apprentissage dans des bouquins, car ils sont en général mieux construit (bouquins récents/à jours et connus/reconnus).
    Les tutos ou autre (le Net en général) comme compléments.
    A l'exception de la doc officielle de Php, c'est à dire :
    http://www.php.net/ ou http://fr2.php.net/
    (et non pas les nombreuses copies voir plagiat du site officiel).

  6. #6
    Membre régulier
    Femme Profil pro
    Développeur Web
    Inscrit en
    Février 2004
    Messages
    282
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2004
    Messages : 282
    Points : 103
    Points
    103
    Par défaut
    Merci beaucoup RunCodePhp pour le conseil et surtout j'ai l'habitude de travailler avec la programmation procédurale avec les bases de données relationnelles. Maintenant je décide de changer (ou évoluer) et de m'orienter vers POO. et j'espere de m'en sortir.

    A propos de mon probleme je dirai c'est bon j'ai compris ce que je dois faire, c'est séparé les 2 codes en deux fichiers :

    Personnage.class.php
    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
    class Personnage
    {
            private $force;
            private $localisation;
            private $experience;
            private $degats;
     
            public function deplacer()
            {
     
            }
     
            public function frapper()
            {
     
            }
     
            public function gagnerExperience()
            {
                $this->experience = $this->experience + 1;
            }  
    }
    index.php (c'est juste un exemple)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <?php
    function chargerClasse ($classe){
            require $classe . '.class.php';
    } 
     spl_autoload_register ('chargerClasse'); 
     $perso = new Personnage();
     ?>
    A l'aide de vous que j'essaie d'améliorer mon niveau en programmation et conception.

  7. #7
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <?php
    function chargerClasse ($classe){
            require $classe . '.class.php';
    } 
     spl_autoload_register ('chargerClasse'); 
     $perso = new Personnage();
     ?>
    Cette fois c'est bon.

    Mais chargerClasse c'est une fonction, donc un code procédural.
    Comme tu as pour objectif d'apprendre la POO, je dirais que toute occasion est bonne pour faire Objet.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?php
    class ClassAutoloader {
        public function __construct() {
            spl_autoload_register(array($this, 'loader'));
        }
     
        private function loader($classe) {
            require $classe . '.class.php';
        }
    }
     
     
    $perso = new Personnage();
    ?>
    Donc ceci aurait été mieux, non ?


    j'ai compris ce que je dois faire, c'est séparé les 2 codes en deux fichiers
    Chaque classe devra être dans un fichier (1 classe = 1 fichier).
    Ce n'est pas totalement obligatoire, mais il est préférable d'adopter ce principe là dû à l'autoloader.

    Aussi il faut comprendre qu'avec le code qu'il y a dans l'autoloader actuellement, ça recherchera les classes toujours au même endroit (même répertoire).
    Ceci peut être un frein à l'organisation/structure des classes, et même de l'ensemble du projet, et c'est pour cette raison que j'avais émis quelques réserve sur l'auto-chargement de classes.


    Une technique (assez courante) serait qu'il soit possible de structurer ces classes comme ceci :
    root/classes/Core (les classes du coeur de son projet)
    root/classes/Application (les classes propre à cette application)
    root/classes/Modules (les classe optionnelles / modulaire, donc selon le besoin/contexte)
    etc ...

    Donc faire en sorte que l'autoloader recherche la classe selon le chemin qu'on lui indique.
    Si on indique : $Machin = new Core_Machin() ça recherchera dans le répertoire "Core".
    Si on indique : $Truc = new Modules_Truc() ça recherchera dans le répertoire "Modules"
    etc ...

    Qui est assez proche (sauf erreur) du principe des NameSpaces (valable qu'à partir de Php 5.3).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 18
    Dernier message: 08/04/2006, 10h39
  2. [POO] Classe PHP super simple Mais j'y arrive pas
    Par mulbek dans le forum Langage
    Réponses: 10
    Dernier message: 17/03/2006, 15h33
  3. [POO] POO et PHP
    Par toure32 dans le forum Langage
    Réponses: 2
    Dernier message: 17/12/2005, 00h37
  4. [POO] Env PHP 5
    Par yanis97 dans le forum Langage
    Réponses: 8
    Dernier message: 09/11/2005, 17h16
  5. [Débutant] équivalent du include() php
    Par R3iTt0R dans le forum ASP
    Réponses: 5
    Dernier message: 07/07/2004, 11h46

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