JeuWeb - Crée ton jeu par navigateur
La POO ( php5 ) - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : La POO ( php5 ) (/showthread.php?tid=497)



La POO ( php5 ) - Klemmth - 26-11-2006

Bonjour à tous Smile
Dans ce tutorial, je vais tenter de vous initier à la POO en php, et plus précisément en php5. Je ne suis pas un professionnel, et je vous demanderai donc de m'excuser et d'être indulgents si vous y voyez des erreurs. Je vous invite à me contacter par mp pour toute remarque/suggestion/demande/...

Ce tutorial s'adresse à tous les niveaux, ou du moins je vais faire de mon mieux pour que ce soit le cas. Je vais bien entendu commencer par les bases pour finir sur les concepts plus avancés.
Néanmoins il est nécessaire de connaître le php pour pouvoir suivre le tuto.

Il est en cours de rédaction, donc ne vous inquiétez pas si vous voyez qu'il manque des choses ( à part bien sûr si le chapitre qui en traite est terminé, dans ce cas n'hésitez pas à me contacter ) Wink

Je vous souhaite une bonne lecture à tous, en espérant que j'aurais pû vous apprendre quelque chose :heuuu:

Sommaire
Partie 1 : Les bases
Chapitre 1 : Introduction
I. La POO, qu'est-ce que c'est ?
II. Pourquoi php5 ?
Chapitre 2 : Créer une classe
I. La base de la base
II. Les attributs
III. Les méthodes
IV. Le constructeur
V. Formalisme
Chapitre 3 : Utiliser une classe
I. Utilisation de la classe à l'intérieur de la classe
II. Utilisation de la classe à l'extérieur de la classe
TP : Un bar en POO !
I. Cahier des charges
II. Indications
III. Correction

Partie 2 : La véritable puissance de la POO
Chapitre 1 : L'héritage de classes
I. Introduction
II. Héritage : extends
III. Visibilité : public/protected/private
IV. L'opérateur de résolution de portée ( :: )
V. "final"



Partie 1 : Les bases


Dans cette partie nous allons voir les bases de la POO. Normalement, une fois cette partie terminée ( si vous avez suivi Wink ) vous serez capables de créer une classe et de l'utiliser dans votre code.


Chapitre I : Introduction

I : La POO, qu'est-ce que c'est ?

La POO, ou Programmation Orientée Objet n'est pas un langage de programmation à proprement parler comme le PHP, ou le C. Il s'agit en fait d'une méthode de programmation. Elle a été inventé afin d'améliorer la lisibilité du code source, sa modularité, et bien d'autres aspects qui rendent la programmation bien plus agréable lorsque l'on utilise la POO.
Vous vous en rendrez compte au fur et à mesure de ce tuto.

Citation :Mais en quoi consiste-t-elle ?

Le principe de la POO est assez simple. En effet, elle se base sur le monde qui nous entoure. Ne définissons-nous pas tout comme étant un objet ?
Et bien la POO reprend le même principe. C'est à dire qu'elle va nous permettre de séparer notre code en différents objets ( appelés classes ) comme dans la réalité.
Par exemple, l'homme peut être considéré comme un objet, le lit comme un autre, etc... Et bien ce sera la même chose en POO, sauf que vos objets seront le joueur, la classe MySQL, la page, etc...

Citation :C'est bien beau tout ça, on a des objets maintenant dans notre code, mais qu'est-ce qu'on en fait ?

Et bien vos objets vont en fait fonctionner comme des bibliothèques ( pour ceux qui ne connaissent pas, il s'agit de fichiers qui regroupent plusieurs fonctions ). C'est à dire qu'ils vont posséder des fonctions ( appelées méthodes ) que vous pourrez appeler à loisir par la suite.

Citation :Quelle est la différence alors avec une bibliothèque ?

Et bien elle est énorme ! En effet, vous pouvez déclarer des variables spécifiques à chaque objet ( appelées attributs ). Ces variables pourront être appelées dans les méthodes, ou en dehors de la classe, et vous pourrez les modifier comme vous voulez.

La différence entre une classe et une bibliothèque peut se voir de cette manière ( imagée ) :
- la bibliothèque, qui porte bien son nom, possède de nombreux livres ( les fonctions ), mais dont on connait seulement le titre ( le nom de la fonction )
- la classe, quant à elle, pourrait être assimilée à une bibliothèque dont on connaît le nom, où l'on pourrait définir sa taille, son poids, l'auteur du livre que l'on recherche, etc...

Pour prendre un exemple plus concret : la main. Elle peut être considérée comme un objet dont les attributs seraient : nombre de doigts, taille des doigts, taille de la main, poids de la main, action en cours,... ; et dont les méthodes seraient : prendre, tourner, bouger un doigt, etc...

Voilà, j'espère que vous aurez compris la différence fondamentale qui existe entre le concept de POO et de bibliothèques grâce à cet exemple ( néanmoins on peut très bien utiliser ces 2 concepts dans un programme ).


Après cette introduction qui, je l'espère, vous aura fait comprendre ce qui se cachait derrière le nom obscur de POO, nous allons pouvoir passer à la pratique, avec son inclusion dans le langage qui nos intéresse : le php.

Citation :Résumé :
POO = Programmation Orientée Objet
un objet = une classe
une fonction d'un objet = une méthode
une variable d'un objet = un attribut
La POO est utilisée dans de nombreux langages, même si ici on ne se concentre que sur le php


II. Pourquoi php5 ?

Citation :Pourquoi tu as choisi de nous présenter la POO en php5 alors que tous les hébergeurs ne le supporte pas ?

En effet, php5 n'a pas été implémenté chez tous les hébergeurs, néanmoins il l'est de plus en plus, et le fait qu'il possède de nombreuses fonctionnalités pratiques m'a décidé à faire ce tuto dessus, plutot que sur php4 ( et puis de toute manière va bien falloir vous décider un jour à passer à php5 :p ).
Néanmoins je ferais de mon mieux pour vous montrer les équivalences en php4 afin que vous ne soyez pas trop désavantagés si votre hébergeur ne supporte pas php5.

De plus, les évolutions depuis php4 en ce qui concerne la POO ne sont pas si nombreuses que ça, et vous ne devriez donc pas avoir trop de mal à faire la transition entre les deux.

Maintenant que c'est dis, passons à la pratique Smile

Citation :Résumé :
Le php5 c'est mieux que le php4 Wink


Chapitre II : Créer une classe

I. La base de la base

Comme je vous l'ai dis plus tôt, les classes sont la base de la POO. Vous allez devoir déclarer ces classes afin de les appeler plus tard dans votre code. Vous pouvez le faire directement dans la page où vous souhaitez l'appeler, mais c'est une méthode que je vous déconseille plus que fortement car vous serez obligés de la recopier pour chaque page où vous l'utilisez, et cela augementera fortement la taille de vos pages.
Je vous conseille donc de créer un fichier à part pour chacune de vos classes, et de l'inclure ensuite dans la page où vous souhaitez utiliser la classe. Vous pouvez l'enregistrer en .inc, en .php, en .php5, etc...
Il est aussi souvent plus pratique de regrouper toutes vos classes dans le même dossier. Dans le cas d'un très gros projet, regroupez les classes selon leur "action" ( exemple : un dossier "systeme", un dossier "game",... )

Une fois que vous avez crée votre nouveau fichier ( pensez à l'enregistrer régulièrement ), nous allons pouvoir écrire notre classe dedans.

Citation :C'est bien beau tout ça, mais ça s'écrit comment une classe ?

Vu que nous sommes ici en php, et que la POO n'est pas un langage de programmation, nous allons avoir la même syntaxe que le php. Vous ne serez donc pas dépaysés Wink

Néanmoins, cela vous oblige à inclure les balises :
Code PHP :
<?php
?>
C'est entre ces balises que va être écrite la classe.

Citation :Comment déclare-t-on la classe ?

Ca se fait d'une manière très simple, comme ceci :
Code PHP :
<?php
class Myclass
{
...
}
?>

class étant bien sûr le mot clé de déclaration de la classe, et "myclass" étant le nom de votre classe ( ça peut bien entendu être tout ce que vous voulez, tant que vous respectez les conventions du php vis à vis de la nomenclature ).

Et voilà, vous avez votre première classe de crée ! Bon ok, elle ne fait rien, et vous ne savez même pas l'utiliser, mais chaque chose en son temps, on ne va pas s'arrêter en si bonne voie Wink

Citation :Résumé :
Pour créer une classe : créer un nouveau fichier où on écrit la classe, puis inclure ce fichier dans le code de la page où on utilise la classe.
Code de base d'une classe :
Code PHP :
<?php
class Myclass
{
}
?>


II. Les attributs

Citation :C'est quoi un attribut ?

Ah je vois tout de suite ceux qui n'ont pas suivi :ninga:
Rappelez vous le début du cours : je vous avais dit qu'un attribut était en fait une variable appartenant à une classe. On peut bien entendu créer plusieurs attributs par classe ( que je sache il n'y a pas de nombre limite ). Ces attributs vont nous permettre de faire des classes regroupant beaucoup d'informations.

Par exemple, si je fais une classe "joueur", je pourrais très bien lui mettre les attributs "pv", "or", "mana", etc...

Il peut bien sûr exister plusieurs attributs du même nom, du moment qu'ils appartiennent à des classes différentes. Exemple : je peux très bien avoir un attribut "pv" pour ma classe "joueur", et un même attribut "pv" pour mon autre classe "ia". Les attributs auront le même nom mais ils ne stockeront pas la même valeur.

Citation :C'est bien joli tout ça, mais ça m'étonnerait qu'on déclare un attribut en mettant son nom entre "". Comment on fait alors ?

La déclaration d'un attribut est très simple, et est à peu près similaire à la déclaration d'une variable classique :
Code PHP :
<?php 
public $myvar;

Citation :En php4 la déclaration se fait de cette façon :
Code PHP :
<?php 
var $myvar;

Vous noterez le mot-clé public. Pour l'instant considérez juste qu'il est nécessaire à la déclaration. Nous verrons dans la partie suivante son utilité réelle.

Bien entendu l'attribut doit être déclaré à l'intérieur de la classe :
Code PHP :
<?php
class Myclass
{
public
$myvar;
}
?>

Vous pouvez déclarer autant d'attributs que vous le souhaitez à la suite, et leur attribuer une valeur directement, comme dans un code php classique Wink

Je vous mets néanmoins un exemple :
Code PHP :
<?php
class Myclass
{
public
$myvar1 = 1;
public
$myvar2;
}
?>

Je pense que vous ne devriez pas avoir trop de mal à retenir cette notion d'attribut car vous l'utiliserez de toute manière tout le temps. Nous allons donc pouvoir passer à une autre notion fondamentale : les méthodes.

Citation :Résumé :
La déclaration d'un attribut se fait à l'intérieur de la classe.
La déclaration se fait de cette manière :
Code PHP :
<?php 
public $myvar;
On peut donner une valeur à l'initiation, et on peut déclarer autant d'attributs qu'on le souhaite.


III. Les méthodes

Citation :C'est quoi une méthode ?

Ralala, toujours les mêmes qui ne suivent pas :non:
Rappelez vous toujours le début du cours : une méthode est une fonction appartenant à une classe.
De la même manière que les attributs, on peut déclarer autant de méthodes que l'on veut par classe, et on peut avoir des méthodes qui ont le même nom dans des classes différentes.

La déclaration d'une méthode est aussi très similaire à la déclaration d'une fonction normale en php :
Code PHP :
<?php 
function myfunction()
{
}

ou encore ( valable seulement en php5 ) :
Code PHP :
<?php 
public function myfunction()
{
}

On retrouve encore le mot clé public qu'on utilisait pour les attributs. Mais nous verrons son utilité seulement dans la prochaine partie, désolé Wink

Bien entendu, comme les fonctions normales, les méthodes acceptent des arguments auxquels on peut donner une valeur d'initiation.

Je donne un exemple pour ceux qui aurait tenter d'aborder ce cours en connaissant très peu le php Wink :
Code PHP :
<?php 
public function afficher( $texteAAfficher, $nbreDeFois=1 ){
}

Tout comme les attributs, les méthodes doivent être déclarées à l'intérieur de la classe. On obtient donc :
Code PHP :
<?php
class Myclass
{
public function
myfunction()
{
}
}
?>

Et voilà, maintenant que vous connaissez les attributs et les méthodes, nous allons pouvoir passer à la dernière chose nécessaire à la déclaration d'une classe : le constructeur

Citation :Résumé :
La déclaration d'une méthode se fait à l'intérieur de la classe.
La déclaration d'une méthode se fait de cette manière :
Code PHP :
<?php 
public function myfunction()
{
}
Le "public" n'est pas nécessaire, car on le sous entend en écrivant :
Code PHP :
<?php 
function myfunction()
{
}
On peut donner aux méthodes des arguments, et on peut en déclarer autant qu'on le souhaite.


IV. Le constructeur

Citation :Un constructeur ? Et pourquoi pas un plombier pendant qu'on y est ?

Et oui, sous ce terme étonnant se cache le dernier élément nécessaire à la création d'une classe. ( en fait il n'est pas obligatoire, mais je préfère qu'il le soit pour vous, car de toute manière vous l'utiliserez à peu près tout le temps Wink )
Il s'agit en fait d'une méthode qui porte bien son nom, puisqu'elle va servir à "construire" la classe, ou plutôt à l'initialiser. C'est depuis cette méthode que vous allez, par exemple, récupérer dans la bdd certaines valeurs pour les attribuer à vos attributs.

Le constructeur se déclare très simplement :
Code PHP :
<?php 
function __construct()
{
}

Citation :En php4 il se déclare de cette manière :
Code PHP :
<?php 
function Myclass()
{
}
"Myclass" étant bien sûr le nom que l'on a donné à notre classe.

Ce constructeur peut accepter des arguments, tout comme une fonction normale. Ces arguments seront les arguments de la classe, c'est à dire qu'ils seront demandés lors de l'appel de la classe ( contrairement aux arguments des méthodes qui ne sont demandés que lors de l'appel de la méthode ). Vous comprendrez mieux dans les prochaines sous-parties.

Je ne vous mets pas d'exemple pour la déclaration du constructeur avec des arguments, car cela fonctionne exactement comme les autres fonctions.

Bien entendu il faut le déclarer à l'intérieur de la classe :
Code PHP :
<?php
class Myclass
{
function
__construct()
{
}
}
?>

Faites attention cependant, il ne peut y avoir qu'un seul constructeur par classe.

Voilà, vous connaissez maintenant la structure complète d'une classe, mais vous ne savez toujours pas l'utiliser. Nous allons maintenant voir comment utiliser les attributs et les méthodes de la classe à l'intérieur même de celle-ci.

Citation :Résumé :
Le constructeur est une méthode obligatoire pour chaque classe, mais il ne doit y en avoir qu'un par classe.
Il accepte des arguments qui seront les arguments demandés lors de l'appel de la classe.
Le constructeur se déclare de cette manière :
Code PHP :
<?php 
function __construct()
{
}

Citation :Schéma de la création d'une classe basique :
Code PHP :
<?php
//on déclare la classe

class Myclass
{
//on déclare les attributs
public $myvar;

//on déclare le constructeur
function __construct()
{
}

//on déclare les méthodes
public function myfunction()
{
}
}

?>


V. Formalisme

Chacun à sa manière de programmer, néamoins dans cette sous partie je vais tenter de vous "initier" aux conventions qui existent en php, et plus particulièrement en POO.

En effet, il est important d'avoir un code propre et clair. Les conventions ont été mis en place dans ce but. Elles sont assez simples à retenir et rendront votre code beaucoup plus agréable Wink

La première en POO, c'est que vous devez commencé le nom de votre classe par une majuscule. Ensuite, les différents mots du nom de la classe doivent être séparés soit par des majuscules, soit par des "_" ( pour ma part j'utilise plutôt les majuscules ).

Ensuite, pour les attributs, je vous conseille de commencer par une minuscule puis de suivre le même principe que pour le nom de la classe ( pour ma part j'utilise les majuscules pour les attributs, et les "_" pour les méthodes ).

Ce qui nous donne ( désolé pour l'exemple pourri :heuuu: ) :
Code PHP :
<?php 
class BarDeFolie
{
public
$boissonABoire;

public function
donner_a_boire()
{
}
}

Dans la partie 2 nous verrons les constantes. J'en profite néanmoins pour vous donner les conventions les concernant : on écrit toujours les constantes en majuscules, avec les mots séparés par des "_".
Ex : "JOLIE_CONSTANTE"

Citation :Résumé :
nom de classe : Majuscule première lettre, puis mots séparés par majuscule ou "_"
attributs et méthodes : Minuscule première lettre, puis mots séparés par majuscule ou "_"
constantes : Majuscules pour toutes les lettres, et mots séparés par des "_"
Faut respecter les conventions Wink


Chapitre 3 : Utiliser une classe

I. Utilisation de la classe à l'intérieur de la classe

Et oui, si je me permets de consacrer une sous partie à ce problème, c'est car on n'appelle pas les fonctions et les variables de la même manière à l'intérieur d'une classe qu'en php normal Wink

Néanmoins, et fort heureusement, ce n'est pas bien compliqué non plus Smile

Vous allez devoir, et mettez-vous bien ça dans la tête car ça ne marchera jamais si vous l'oubliez, utiliser $this-> avant le nom de votre attribut ou méthode.
$this représente en fait la classe que l'on appelle. Ici comme on se trouve à l'intérieur même de la classe, ben on utilise ça Wink
-> représente le fait que l'on va chercher quelque chose dans la classe ( $this ). Vous utiliserez ce signe tout le temps et partout en POO en php, donc souvenez vous en.

Ce qui va nous donner donc pour appeler un attribut ou une méthode à l'intérieur de la classe :
Code PHP :
<?php 
$this
->myvar; //j'appelle un attribut
$this->myfunction(); //j'appelle une méthode

Attention : vous noterez qu'il n'y a pas de $ avant le nom de l'attribut ou de la méthode. En effet, on ne le trouve que devant le "this".

Et voilà maintenant que vous savez utiliser votre classe à l'intérieur, nous allons pouvoir voir comment l'utiliser à l'extérieur. Vous verrez que c'est très similaire et qu'il n'y a rien de difficile Wink

Citation :Résumé :
Appel d'un attribut ou d'une méthode à l'intérieur de la classe :
Code PHP :
<?php 
$this
->...
Pas de $ avant le nom de l'attribut ou de la methode, seulement avant le "this"


II. Utilisation de la classe à l'extérieur de la classe

Cette sous-partie va être à peine plus compliqué. Et oui, par chance la POO s'utilise très facilement en php Wink

Tout d'abord, une chose très importante, et de toute manière nécessaire : la déclaration de l'objet dans la page où vous voulez l'utiliser.
En effet, vous savez sûrement qu'il existe plusieurs types de variables : les int, les string, bool, etc...
Et bien votre classe va être utilisée dans votre page elle aussi sous la forme d'une variable : une variable de type objet ( ou object ).
Mais la déclaration de l'objet va être un peu différente de celle d'une variable "classique". Vous vous rappelez peut-être que le constructeur supporte des arguments ? Si ce n'est pas le cas je vous conseille de retourner en arrière Wink
Et bien tout comme lors de l'appel d'une fonction, il va vous falloir donner une valeur à ces arguments lors de la déclaration de l'objet.
De plus, vous devrez utiliser le mot-clé new pour bien préciser que votre variable est bien un objet ( et oui, le php ne fait pas encore tout à votre place Smile ).

Attention : je vous rappelle qu'il vous faut obligatoirement avoir inclus le fichier contenant votre classe avant de pouvoir la déclarer dans votre page.

Voici donc la déclaration classique d'un objet :
Code PHP :
<?php 
$myobject
= new Myclass(); //s'il y a des arguments pour le constructeur, on doit bien sûr les définir entre les ()

Vous pouvez déclarer plusieurs objets de la même classe avec des arguments différents si nécessaire :
Code PHP :
<?php 
$myobject1
= new Myclass( 1 ); //il faut bien sûr que la classe myclass possède un attribut ( par exemple $arg1 ) et qu'il soit demandé en argument du constructeur
$myobject2 = new Myclass( 2 );

Citation :C'est bien beau tout ça, je sais déclarer ma classe, l'appeler dans ma page, mais je ne sais toujours pas l'utiliser !

Et bien l'utilisation de la classe dans votre page est tout aussi simple qu'à l'intérieur de la classe elle-même. Sauf que cette fois, au lieu du mot clé this, vous allez utiliser le nom de votre objet.

Si on reprend l'exemple précédent :
Code PHP :
<?php 
$myobject1
= new Myclass( 1 );
$myobject2 = new Myclass( 2 );

echo
$myobject1->arg1; //affichera 1
echo $myobject2->arg1; //affichera 2

Et voilà, rien de plus simple ! C'est le même procédé pour appeler les attributs et les méthodes.

Citation :Résumé :
une variable de classe est un objet
Déclaration d'un objet :
Code PHP :
<?php 
$myobject
= new Myclass();
Appel d'un attribut ou d'une methode :
Code PHP :
<?php 
$myobject
->myvar;
$myobject->myfunction();
On peut déclarer plusieurs objets pour la même classe.
On doit passer les arguments au constructeur lors de la déclaration de l'objet.

Vous êtes enfin arriver aux bouts de vos ( premières ) peines. Vous pouvez maintenant créer des classes pleinement fonctionnelles et vous en servir. Mine de rien tout le monde ne peut pas en dire autant Wink
Je vous conseille de bien revoir cette partie, de connaître parfaitement les bases avant de passer à la suite, car ce serait dommage que vous abandonniez parce que vous ne comprenez pas alors qu'il aurait suffit que vous connaissiez mieux les bases.

Sur ce, passons à la suite, où nous commencerons enfin à comprendre la puissance du POO et l'utilité de php5 Smile


TP : Un bar en POO !

Bienvenue dans vote premier TP ( sur ce tuto du moins Wink ) !
Dans ce TP, nous allons tenter de réaliser une classe "bar". Normalement les seuls problèmes que vous pourriez rencontrer doivent être des problèmes purement liés au php et non à la POO. Si c'est le cas ce n'est pas trop grave, car nous ne sommes pas là pour apprendre le php ( néanmoins il va vous falloir avoir un certain niveau en php pour les prochaines parties ). Par contre, si les problèmes que vous rencontrez sont liés à la POO, je vous conseille fortement de revoir cette partie avant de passer à la suite. En effet nous verrons après des notions pour lesquelles il sera nécessaire que vous soyez parfaitement à l'aise avec les bases. Ce TP n'a normalement rien de dur, mais sa "longueur" ( 500 lignes environ chez moi avec beaucoup de commentaires ) vous permettra de vous habituer à l'utilisation du "$this->" et des autres bases de la POO Wink


I. Cahier des charges

Nous allons maintenant établir le cahier des charges. Suivez le au mieux, mais ce n'est pas grave s'il y a certaines choses que vous n'arrivez pas à faire, ou si vous en faites plus ( ça c'est encore mieux Wink ). Néanmoins n'abandonnez pas avant d'avoir vraiment essayé.

Cahier des charges :

- L'utilisateur doit pouvoir définir au départ : le nom du bar, le nom du barman, les alcools en stock, les alcools max ( nom de l'alcool avec nombre de bouteilles max pour cet alcool ), le nombre de clients max, et les clients actuels

- La classe doit comporter des méthodes d'affichage suffisantes pour afficher la plupart des informations

- La classe doit comporter des méthodes de modification ( modification, ajout, suppression ) permettant de modifier le maximum d'attributs.

- Pour finir, la classe doit comporter des méthodes permettant de gérer le stock : c'est à dire des méthodes permettant de : vérifier que le stock est complet, vider le stock, refaire le stock.


II. Indications

Ces indications ne doivent pas forcément être suivies, elles sont justes là pour vous donner un coup de main et vous aider à démarrer. Libre à vous de les suivre ou non Wink

Tout d'abord on va se mettre d'accord avec les attributs à utiliser ( vous pouvez bien sur en ajouter ou en retirer selon vos besoins, mais ce sont ceux que j'ai utilisé ) :
Code PHP :
<?php 
public $nomBar;
public
$nomBarman;
public
$alcoolsEnStock = array(); // tableau associatif : nom de l'alcool => nombre de bouteilles en stock
public $alcoolsMax = array(); // tableau associatif : nom de l'alcool => nombre de bouteilles max
public $clientsActuels = array(); // tableau indexé : alcool bu par les clients
public $nbreClientsMax;
public
$nbreClientsActuels;
public
$nbreAlcoolsMax;
public
$nbreAlcoolsEnStock;
public
$nbreBouteillesMax;
public
$nbreBouteillesEnStock;

Ensuite, pour récupérer le nom de l'alcool, je vous conseille de passer par la fonction key() avec l'aide de current(), next(),
et reset() pour parcourir le tableau. Vous pouvez aussi utiliser : array_keys(), et array_key_exists().

Voilà, ce sont normalement les seuls difficultés que vous auriez pu rencontrer. Sur ce, je vous laisse et vous souhaite bonne chance pour ce TP Wink


III. Correction

Voici la correction. Encore une fois ne continuez pas si vous n'avez même pas essayé, ça ne sert à rien Wink
Normalement le code est assez commenté pour être compréhensible, je n'en rajouterai donc pas.

Code PHP :
<?php

/**
* class Bar
*
* Permet de gérer un bar
*
*/
class Bar
{

/***************************************************************************************************************/
/* Déclaration des attributs /
/***************************************************************************************************************/
public $nomBar;
public
$nomBarman;
public
$alcoolsEnStock = array(); // tableau associatif : nom de l'alcool => nombre de bouteilles en stock
public $alcoolsMax = array(); // tableau associatif : nom de l'alcool => nombre de bouteilles max
public $clientsActuels = array(); // tableau indexé : alcool bu par les clients
public $nbreClientsMax;
public
$nbreClientsActuels;
public
$nbreAlcoolsMax;
public
$nbreAlcoolsEnStock;
public
$nbreBouteillesMax;
public
$nbreBouteillesEnStock;
/***************************************************************************************************************/
/* Fin de déclaration des attributs /
/***************************************************************************************************************/

/**
* __construct
* Initialise les attributs suivant les informations données par l'utilisateur
*
* @param string $nomBar nom du bar
* @param string $nomBarman nom du barman
* @param array( string => integer ) $alcoolsEnStock tableau associatif : nom de l'alcool => nombre de bouteilles en stock
* @param array( string => integer ) $alcoolsMax tableau associatif : nom de l'alcool => nombre de bouteilles max
* @param integer $nbreClientsMax nombre de clients maximum que le bar accepte
* @param array( string ) $clientsActuels tableau indexé : alcool bu par les clients
*/
function __construct( $nomBar="", $nomBarman="", $alcoolsEnStock=array(), $alcoolsMax=array(), $nbreClientsMax=10, $clientsActuels=array() )
{
$this->nomBar = $nomBar;
$this->nomBarman = $nomBarman;

if(
is_array( $alcoolsEnStock ) ) // on vérifie que les informations envoyées soient bien des tableaux
$this->alcoolsEnStock = $alcoolsEnStock;
if(
is_array( $alcoolsMax ) )
$this->alcoolsMax = $alcoolsMax;

$this->nbreClientsMax = $nbreClientsMax;
if(
is_array( $clientsActuels ) )
$this->clientsActuels = $clientsActuels;

$this->nbreClientsActuels = count( $clientsActuels ); // on compte les différents informations
$this->nbreAlcoolsMax = count( $alcoolsMax );
$this->nbreAlcoolsEnStock = count( $alcoolsEnStock );

$this->nbreBouteillesMax = 0;
$this->nbreBouteillesEnStock = 0;

// boucle qui va servir à compter le nombre de bouteilles max
while( $nbreBouteilles = current( $this->alcoolsMax ) )
{
$this->nbreBouteillesMax += $nbreBouteilles;
next( $this->alcoolsMax );
}
reset( $this->alcoolsMax );

// boucle qui va servir à compter le nombre de bouteilles en stock
while( $nbreBouteilles = current( $this->alcoolsEnStock ) )
{
$this->nbreBouteillesEnStock += $nbreBouteilles;
next( $this->alcoolsEnStock );
}
reset( $this->alcoolsEnStock );
}


/***************************************************************************************************************/
/* Bloc : méthodes d'affichage /
/***************************************************************************************************************/
/**
* afficher_alcools_possibles
* Affiche le nom des alcools possibles
*/
public function afficher_alcools_possibles()
{
$nomsAlcools = array_keys( $this->alcoolsMax ); // on récupère le nom des alcools

foreach( $nomsAlcools as $nom ) // on les affiche
{
echo
$nom."<br />\n";
}
}

/**
* afficher_alcools_disponibles
* Affiche le nom des alcools disponibles
*/
public function afficher_alcools_disponibles()
{
$nomsAlcools = array_keys( $this->alcoolsEnStock );

foreach(
$nomsAlcools as $nom )
{
if(
$this->alcoolsEnStock[$nom] > 0 ) // on vérifie qu'il y ait bien des bouteilles en stock pour cet alcool
echo $nom."<br />\n";
}
}

/**
* afficher_bouteilles_possibles
* Affiche le nom des alcools possibles suivi du nombre de bouteilles possibles pour ces alcools
*/
public function afficher_bouteilles_possibles()
{
// boucle qui parcourt le tableau jusqu'à sa fin
while( $nbreBouteilles = current( $this->alcoolsMax ) )
{
echo
"Bouteilles possibles de ".key( $this->alcoolsMax )." : ".$nbreBouteilles."<br />\n"; // on récupère le nom de l'alcool avec key() et on l'affiche suivi du nombre de bouteilles correspondant
next( $this->alcoolsMax );
}
reset( $this->alcoolsMax ); // on rembobine le tableau que l'on vient de parcourir
}

/**
* afficher_bouteilles_disponibles
* Affiche le nom des alcools disponibles suivi du nombre de bouteilles en stock pour ces alcools
*/
public function afficher_bouteilles_disponibles()
{
while(
$nbreBouteilles = current( $this->alcoolsEnStock ) )
{
echo
"Bouteilles en stock de ".key( $this->alcoolsEnStock )." : ".$nbreBouteilles."<br />\n";
next( $this->alcoolsEnStock );
}
reset( $this->alcoolsEnStock );
}

/**
* afficher_clients_actuels
* Affiche ce que boivent les différents clients
*/
public function afficher_clients_actuels()
{
$i = 0;

// boucle qui parcourt le tableau des clients
for( $i=0; $i<count( $this->clientsActuels ); $i++ )
{
if( !empty(
$this->clientsActuels[$i] ) ) // on vérifie qu'il y ait bien un client dans cet emplacement du tableau
echo "Client ".( $i+1 )." boit : ".$this->clientsActuels[$i]."<br />\n";
}
}

/**
* afficher_bar
* Affiche toutes les infos concernant le bar
*/
public function afficher_bar()
{
echo
"Nom du bar : ".$this->nomBar."<br />\n";
echo
"Nom du barman : ".$this->nomBarman."<br /><br />\n";

echo
"Nombre d'alcools possibles : ".$this->nbreAlcoolsMax."<br />\n";
echo
"Alcools possibles :<br />\n";
$this->afficher_alcools_possibles();
echo
"<br />\n";

echo
"Nombre de bouteilles possibles : ".$this->nbreBouteillesMax."<br />\n";
echo
"Bouteilles possibles :<br />\n";
$this->afficher_bouteilles_possibles();
echo
"<br />\n";

echo
"Nombre d'alcools disponibles : ".$this->nbreAlcoolsEnStock."<br />\n";
echo
"Alcools disponibles :<br />\n";
$this->afficher_alcools_disponibles();
echo
"<br />\n";

echo
"Nombre de bouteilles disponibles : ".$this->nbreBouteillesEnStock."<br />\n";
echo
"Bouteilles disponibles :<br />\n";
$this->afficher_bouteilles_disponibles();
echo
"<br />\n";

echo
"Nombre de clients possibles : ".$this->nbreClientsMax."<br />\n";
echo
"Nombre de clients actuels : ".$this->nbreClientsActuels."<br />\n";
echo
"Clients actuels :<br />\n";
$this->afficher_clients_actuels();
echo
"<br />\n";
}
/***************************************************************************************************************/
/* Fin du bloc : méthodes d'affichage /
/***************************************************************************************************************/

/***************************************************************************************************************/
/* Bloc : méthodes de modifications /
/***************************************************************************************************************/
/**
* modifier_bouteilles_max
* Modifie le nombre maximum de bouteilles
*
* @param string $nomAlcool nom de l'alcool dont il faut modifier le nombre de bouteilles
* @param integer $nbreBouteillesMax nombre de bouteilles maximum qu'il doit y avoir
* @return boolean Réussite ou non de la modification
*/
public function modifier_bouteilles_max( $nomAlcool="", $nbreBouteillesMax=1 )
{
if(
array_key_exists( $nomAlcool, $this->alcoolsMax ) && $nbreBouteillesMax > 0 ) // on vérifie que l'alcool existe bien et que l'utilisateur n'a pas rentré un nombre inférieur à 0
{
// on modifie le nombre de bouteilles max
$this->nbreBouteillesMax -= $this->alcoolsMax[$nomAlcool];
$this->alcoolsMax[$nomAlcool] = $nbreBouteillesMax;
$this->nbreBouteillesMax += $nbreBouteillesMax;

// si le nombre max est inférieur au nombre en stock, on réajuste le nombre en stock
if( $this->alcoolsMax[$nomAlcool] < $this->alcoolsEnStock[$nomAlcool] )
$this->modifier_bouteilles_enstock( $nomAlcool, $this->alcoolsMax[$nomAlcool] );

return
TRUE; // tout s'est bien passé
}
return
FALSE; // il y a eu un problème, la modification n'a pas pu se faire
}

/**
* modifier_bouteilles_enstock
* Modifie le nombre de bouteilles en stock
*
* @param string $nomAlcool nom de l'alcool dont il faut modifier le nombre de bouteilles
* @param integer $nbreBouteillesMax nombre de bouteilles en stock qu'il doit y avoir
* @return boolean Réussite ou non de la modification
*/
public function modifier_bouteilles_enstock( $nomAlcool="", $nbreBouteillesEnStock=1 )
{
if(
array_key_exists( $nomAlcool, $this->alcoolsEnStock ) && $nbreBouteillesEnStock > 0 )
{
if(
$nbreBouteillesEnStock <= $this->alcoolsMax[$nomAlcool] )
{
$this->nbreBouteillesEnStock -= $this->alcoolsEnStock[$nomAlcool];
$this->alcoolsEnStock[$nomAlcool] = $nbreBouteillesEnStock;
$this->nbreBouteillesEnStock += $nbreBouteillesEnStock;
return
TRUE;
}
}
return
FALSE;
}

/**
* modifier_clients_max
* Modifie le nombre de clients max, en virant le surplus de clients actuels
*
* @param integer $nbreClientsMax nombre de clients max qu'il doit y avoir
* @return boolean Réussite ou non de la modification
*/
public function modifier_clients_max( $nbreClientsMax = 1 )
{
if(
$nbreClientsMax > 0 )
{
$this->nbreClientsMax = $nbreClientsMax;

// on réajuste en virant les derniers clients si jamais le nombre max de clients est inférieur au nombre actuel
while ( $this->nbreClientsMax < $this->nbreClientsActuels )
{
unset(
$this->ClientsActuels[ ( count( $this->ClientsActuels ) - 1 ) ] );
$this->nbreClientsActuels--;
}
return
TRUE;
}
return
FALSE;
}


/**
* ajouter_alcool
* Ajoute un alcool dans les alcools disponibles ( max et en stock )
*
* @param string $nomAlcool nom de l'alcool qu'il faut ajouter
* @param integer $nbreBouteillesMax nombre de bouteilles maximum qu'il doit y avoir pour cet alcool
* @param integer $nbreBouteillesEnStock nombre de bouteilles en stock qu'il doit y avoir pour cet alcool
* @return boolean Réussite ou non de l'ajout
*/
public function ajouter_alcool( $nomAlcool="", $nbreBouteillesMax=1, $nbreBouteillesEnStock=1 )
{
if( !
array_key_exists( $nomAlcool, $this->alcoolsMax ) && !array_key_exists( $nomAlcool, $this->alcoolsEnStock ) )
{
// on va créer un tableau depuis les informations concernant l'alcool à ajouter max et en stock, et on va le mélanger avec le tableau existant
$alcoolAAjouterMax = array( $nomAlcool => $nbreBouteillesMax );
$alcoolAAjouterEnStock = array( $nomAlcool => $nbreBouteillesEnStock );
$this->alcoolsMax = array_merge( $this->alcoolsMax, $alcoolAAjouterMax );
$this->alcoolsEnStock = array_merge( $this->alcoolsEnStock, $alcoolAAjouterEnStock );

$this->nbreAlcoolsMax++;
$this->nbreAlcoolsEnStock++;
$this->nbreBouteillesMax += $nbreBouteillesMax;
$this->nbreBouteillesEnStock += $nbreBouteillesEnStock;

return
TRUE;
}
return
FALSE;
}

/**
* ajouter_client
* Ajoute un client dans la liste des clients actuels
*
* @param string $alcoolBu nom de l'alcool bu par le client
* @return boolean Réussite ou non de l'ajout
*/
public function ajouter_client( $alcoolBu="" )
{
if(
array_key_exists( $alcoolBu, $this->alcoolsEnStock ) && $this->nbreClientsActuels < $this->nbreClientsMax )
{
$i=0;

// boucle qui parcourt le tableau des clients pour chercher un emplacement vide
for( $i=0; $i<=count( $this->clientsActuels ); $i++ )
{
if( empty(
$this->clientsActuels[$i] ) ) // l'emplacement est vide, donc on y ajoute le nouveau client
{
$this->clientsActuels[$i] = $alcoolBu;
$this->nbreClientsActuels++;
return
TRUE;
}
}
}
return
FALSE;
}

/**
* ajouter_client_max
* Augmente d'1 le nombre de clients max
*
* @return boolean Réussite ou non de l'ajout
*/
public function ajouter_client_max()
{
return
$this->modifier_clients_max( $this->nbreClientsMax + 1 );
}

/**
* ajouter_bouteille_max
* Augmente d'1 le nombre de bouteilles max pour un alcool
*
* @param string $nomAlcool nom de l'alcool pour lequel il faut rajouter une bouteille
* @return boolean Réussite ou non de l'ajout
*/
public function ajouter_bouteille_max( $nomAlcool="" )
{
if(
array_key_exists( $nomAlcool, $this->alcoolsMax ) )
return
$this->modifier_bouteilles_max( $nomAlcool, $this->alcoolsMax[$nomAlcool] + 1 );

return
FALSE;
}

/**
* ajouter_bouteille_enstock
* Augmente d'1 le nombre de bouteilles en stock pour un alcool
*
* @param string $nomAlcool nom de l'alcool pour lequel il faut rajouter une bouteille
* @return boolean Réussite ou non de l'ajout
*/
public function ajouter_bouteille_enstock( $nomAlcool="" )
{
if(
array_key_exists( $nomAlcool, $this->alcoolsEnStock ) )
return
$this->modifier_bouteilles_enstock( $nomAlcool, $this->alcoolsEnStock[$nomAlcool] + 1 );

return
FALSE;
}


/**
* retirer_alcool
* Retire complètement un alcool ( max et en stock )
*
* @param string $alcoolARetirer nom de l'alcool à retirer
* @return boolean Réussite ou non de la suppression
*/
public function retirer_alcool( $alcoolARetirer = "" )
{
// on vérifie que l'alcool demandé existe bien et si c'est le cas on le retire des alcools possibles et en stock
if( ( array_key_exists( $alcoolARetirer, $this->alcoolsMax ) && array_key_exists( $alcoolARetirer, $this->alcoolsEnStock ) ) && ( $this->nbreAlcoolsMax > 0 && $this->nbreAlcoolsEnStock > 0 ) )
{
unset(
$this->alcoolsMax[$alcoolARetirer] );
unset(
$this->alcoolsEnStock[$alcoolARetirer] );
$this->nbreAlcoolsMax--;
$this->nbreAlcoolsEnStock--;
return
TRUE;
}
return
FALSE;
}

/**
* retirer_client
* Retire un client de la liste des clients actuels
*
* @param integer $idClientARetirer id du client à retirer ( nouméro qui s'affiche lorsque l'on fait un afficher_bar() )
* @return boolean Réussite ou non de la suppression
*/
public function retirer_client( $idClientARetirer = 0 )
{
// si l'id du client n'a pas été défini, on prend le dernier client de la liste
if( !$idClientARetirer )
$idClientARetirer = count( $this->clientsActuels );

if(
$this->nbreClientsActuels > 0 )
{
if( !empty(
$this->clientsActuels[($idClientARetirer - 1)] ) )
{
unset(
$this->clientsActuels[($idClientARetirer - 1)] );
$this->nbreClientsActuels--;
return
TRUE;
}
}
return
FALSE;
}

/**
* retirer_client_max
* Diminue d'1 le nombre de clients max
*
* @return boolean Réussite ou non de la suppression
*/
public function retirer_client_max()
{
if(
$this->nbreClientsMax > 0 )
return
$this->modifier_clients_max( $this->nbreClientsMax - 1 );

return
FALSE;
}

/**
* retirer_bouteille_max
* Diminue d'1 le nombre de bouteilles max pour un alcool
*
* @param string $nomAlcool nom de l'alcool pour lequel il faut diminuer d'1 le nombre de bouteilles max
* @return boolean Réussite ou non de la suppression
*/
public function retirer_bouteille_max( $nomAlcool="" )
{
if(
array_key_exists( $nomAlcool, $this->alcoolsMax ) )
return
$this->modifier_bouteilles_max( $nomAlcool, $this->alcoolsMax[$nomAlcool] - 1 );

return
FALSE;
}

/**
* retirer_bouteille_enstock
* Diminue d'1 le nombre de bouteilles en stock pour un alcool
*
* @param string $nomAlcool nom de l'alcool pour lequel il faut diminuer d'1 le nombre de bouteilles en stock
* @return boolean Réussite ou non de la suppression
*/
public function retirer_bouteille_enstock( $nomAlcool="" )
{
if(
array_key_exists( $nomAlcool, $this->alcoolsEnStock ) )
return
$this->modifier_bouteilles_enstock( $nomAlcool, $this->alcoolsEnStock[$nomAlcool] - 1 );

return
FALSE;
}
/***************************************************************************************************************/
/* Fin du bloc : méthodes de modifications /
/***************************************************************************************************************/

/***************************************************************************************************************/
/* Bloc : méthodes du stock /
/***************************************************************************************************************/
/**
* is_stock_complet
* Regarde si le stock de bouteilles est complet ( nombre en stock = nombre max )
*
* @return boolean Stock plein ou pas
*/
public function is_stock_complet()
{
return (
$this->nbreBouteillesEnStock == $this->nbreBouteillesMax );
}

/**
* refaire_stock
* Refait le stock : fais en sorte qu'il y ait autant de bouteilles en stock que de bouteilles max
*/
public function refaire_stock()
{
while(
$nbreBouteilles = current( $this->alcoolsMax ) )
{
$this->alcoolsEnStock[key( $this->alcoolsMax )] = $nbreBouteilles;
next( $this->alcoolsMax );
}
reset( $this->alcoolsMax );
$this->nbreBouteillesEnStock = $this->nbreBouteillesMax;
}

/**
* vider_stock
* Vide le stock : fais en sorte qu'il n'y ait plus de bouteilles en stock
*/
public function vider_stock()
{
while(
$nbreBouteilles = current( $this->alcoolsMax ) )
{
$this->alcoolsEnStock[key( $this->alcoolsMax )] = 0;
next( $this->alcoolsMax );
}
reset( $this->alcoolsMax );
$this->nbreBouteillesEnStock = 0;
}
/***************************************************************************************************************/
/* Fin du bloc : méthodes du stock /
/***************************************************************************************************************/

}

?>

Et voilà ! Un peu long, mais pas trop compliqué normalement. J'espère ue vous avez réussi ce TP, ou du moins que vous avez essayé. Si c'est le cas, vous devez être capable de passer à la suite Smile
La prochaine partie n'est pas spécialement compliquée, mais elle va vous permettre d'appréhender de nombreux concepts de la POO des plus importants ( et pratiques Wink ).

Sur ce, passons à la partie 2 Smile



Partie 2 : La véritable puissance de la POO


Bienvenue à tous dans cette deuxième partie Smile
Je vais tâcher ici de vous présenter la plupart des fonctionnalités importantes de la POO en php5. J'essayerai de faire encore des comparaisons avec php4, mais à part pour le chapitre 1, il n'y en a maintenant presque plus, donc il est maintenant vraiment temps de passer à php5 Wink

NB : je rajoute un point de vocabulaire dont je n'avais pas parlé avant : un objet ( c'est à dire la variable contenant votre classe dans votre page ) peut aussi être appelé une "instance de classe". Voilà, c'est tout Smile


Chapitre I : L'héritage de classes

I : Introduction

Dans ce chapitre nous allons voir l'un des concepts les plus importants de la POO. En effet, vous vous servirez souvent de l'héritage de classes, et c'est un concept qu'il vous faudra avoir parfaitement assimilé Wink

Citation :C'est cool, on peut hériter même en POO maintenant... mais ça sert à quoi ?

Et bien comme son nom l'indique, vous allez réellement hériter Wink
C'est à dire que votre classe "fille" va hériter des attributs et des méthodes de votre classe "mère".

Par exemple, j'ai crée 2 classes : une classe restaurant, et une classe bar qui est une classe fille de la classe restaurant. J'ai déclaré dans ma classe restaurant une méthode "afficher_restaurant()" ( référence au "afficher_bar()" du TP Wink ). Et bien si je déclare un nouvel objet "bar", je pourrais directement appeler la méthode "afficher_restaurant()" sans avoir à déclarer un objet "restaurant". Pas mal non ? Wink
Et ce n'est pas tout, mais nous allons voir au fur et à mesure toutes les possibilités.


II. Héritage : extends

Et oui, la base de l'héritage va passer par le mot clé extends. En effet, ce mot clé va vous permettre de préciser que la classe en question est la fille d'une autre classe.
Il vous suffit de déclarer la classe comme nous l'avons appris, puis d'ajouter derrière le nom de la classe : "extends ClasseMere"
Exemple :
Code PHP :
<?php 
class ClasseFille extends ClasseMere
{
}

Une fois que vous aurez fait cela, votre classe fille sera considérée comme fille de votre classe mère, et elle héritera sans que vous ayez besoin de les déclarer de nouveau dans la classe fille des attributs et méthodes de la classe mère excepté pour les fonctions magiques comme __construct(). Nous verrons plus tard ce que sont les fonctions magiques, pour l'instant retenez juste qu'il vous faut redéclarer le constructeur pour la classe fille ( il peut être différent de la classe mère bien entendu ).

Vous pouvez aussi si vous le souhaitez, redéclarer les attributs ou les méthodes dans la classe fille. Dans ce cas, ce sera la redéclaration qui sera prise en compte.

De plus, vous pouvez ajouter des attributs et des méthodes à la classe fille qui lui seront spécifiques.

NB : Vous pouvez bien sûr écrire vos classes dans des fichiers différents. Néanmoins, la classe mère doit être inclue avant la classe fille

Attention : Il ne peut pas y avoir d'héritage successif. C'est à dire qu'on ne peut créer une classe fille d'une classe fille. Néanmoins on peut créer plusieurs classes filles d'une même classe mère.

Voici un petit exemple pour vous aider :
Code PHP :
<?php

//les classes
class Restaurant
{
public
$nomRestaurant = "Le St Louis";
public
$nbreClients;
public
$nbreServeurs;

function
__construct()
{
$this->nbreClients = 50;
$this->nbreServeurs = 7;
}

public function
afficher()
{
echo
$this->nomRestaurant.", ".$this->nbreClients.", ".$this->nbreServeurs;
}
}

class
Bar extends Restaurant
{
public
$nomBar;

function
__construct()
{
$this->nomBar = "Bar du St Louis";
$this->nbreClients = 10;
$this->nbreServeurs = 1;
}

public function
afficher()
{
echo
"Bar : ".$this->nomRestaurant.", ".$this->nomBar.", ".$this->nbreClients.", ".$this->nbreServeurs;
}
}
?>
Code PHP :
<?php
$bar
= new Bar();
$bar->afficher(); //affiche : "Bar : Le St Louis, Bar du St Louis, 10, 1"
echo "<br />";

$restaurant = new Restaurant();
$restaurant->afficher(); //affiche : "Le St Louis, 50, 7"
echo "<br />";

$bar->afficher(); //affiche : "Bar : Le St Louis, Bar du St Louis, 10, 1"
?>

Voilà, j'espère que cet exemple vous aura permis de mieux comprendre ce qui se cache derrière l'héritage de classe Wink

Citation :Le php4 est ici similaire au php5

Citation :Résumé :
Pour déclarer une classe fille : "class ClasseFille extends ClasseMere"
Une classe fille hérite des attributs et des méthodes de la classe mère
Une classe fille peut redéclarer des attributs ou des méthodes de la classe mère
Le constructeur doit être redéclaré dans la classe fille
Une classe fille peut avoir des attributs et des méthodes qui lui sont spécifiques
L'héritage successif est impossible, mais on peut avoir plusieurs classes filles d'une même classe mère


III. Visibilité : public/protected/private


[en cours de rédaction]


RE: La POO ( php5 ) - Kevin - 26-12-2006

L'aide pour ce tutoriel ce trouve à cette adresse :
http://www.jeuweb.org/board/showthread.php?tid=847