Précédent   Forum des professionnels en informatique > PHP > Langage
Langage Forum sur le langage PHP, la POO, les conventions, la sécurité, etc. Avant de poster : FAQ Langage, toutes les FAQ PHP, cours langage et sources PHP
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 25/01/2012, 04h30   #1
Nouveau Membre du Club
 
Femme Bouchra
Inscription : février 2004
Messages : 172
Détails du profil
Informations personnelles :
Nom : Femme Bouchra

Informations forums :
Inscription : février 2004
Messages : 172
Points : 28
Points : 28
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 :
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.
wperle est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/01/2012, 06h21   #2
Expert Confirmé
 
Avatar de RunCodePhp
 
Inscription : janvier 2010
Messages : 2 727
Détails du profil
Informations personnelles :
Localisation : Réunion

Informations forums :
Inscription : janvier 2010
Messages : 2 727
Points : 3 294
Points : 3 294
Salut

Regarde ton code, tu fais en gros ceci :
Code :
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 :
spl_autoload_register ('Personnage::chargerClasse')
- Et si la méthode de classe n'est pas statique :
Code :
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 :
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 :
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();
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]
RunCodePhp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/01/2012, 10h59   #3
Modératrice
 
Avatar de Celira
 
Femme
Développeuse PHP/Java
Inscription : avril 2007
Messages : 3 671
Détails du profil
Informations personnelles :
Sexe : Femme
Âge : 27
Localisation : France

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

Informations forums :
Inscription : avril 2007
Messages : 3 671
Points : 5 404
Points : 5 404
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 :
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;
}
__________________
Modératrice PHP
Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)

Pour afficher votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur)
Celira est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/01/2012, 15h56   #4
Nouveau Membre du Club
 
Femme Bouchra
Inscription : février 2004
Messages : 172
Détails du profil
Informations personnelles :
Nom : Femme Bouchra

Informations forums :
Inscription : février 2004
Messages : 172
Points : 28
Points : 28
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 :
Citation:
bla bla bla
Code :
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 :
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 :
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 :
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 :
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.
wperle est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/01/2012, 19h47   #5
Expert Confirmé
 
Avatar de RunCodePhp
 
Inscription : janvier 2010
Messages : 2 727
Détails du profil
Informations personnelles :
Localisation : Réunion

Informations forums :
Inscription : janvier 2010
Messages : 2 727
Points : 3 294
Points : 3 294
Citation:
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).
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]
RunCodePhp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/01/2012, 20h43   #6
Nouveau Membre du Club
 
Femme Bouchra
Inscription : février 2004
Messages : 172
Détails du profil
Informations personnelles :
Nom : Femme Bouchra

Informations forums :
Inscription : février 2004
Messages : 172
Points : 28
Points : 28
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 :
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 :
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.
wperle est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/01/2012, 07h07   #7
Expert Confirmé
 
Avatar de RunCodePhp
 
Inscription : janvier 2010
Messages : 2 727
Détails du profil
Informations personnelles :
Localisation : Réunion

Informations forums :
Inscription : janvier 2010
Messages : 2 727
Points : 3 294
Points : 3 294
Code :
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 :
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 ?


Citation:
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).
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]
RunCodePhp est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h57.


 
 
 
 
Partenaires

Hébergement Web