Vous êtes sur la page 1sur 14

Editions ENI

PHP 5 - MySQL 5 - AJAX


Entraînez-vous à créer des
applications professionnelles

dans la collection
Les TP Informatiques

Extrait
Accès aux données MySQL 5 depuis PHP
49
ÉNONCÉS DU CHAPITRE 4

Chapitre 4 : Accès aux données MySQL 5 depuis PHP


; Durée : 5 heures 50
; Mots-clés : requêtes SQL, présentation de données, connexion php-mysql, attache-
ment de fichiers, persistance, serveurs d’applications

; Objectif
Une fois l’installation de la base de données accomplie, se pose la question de sa mise
en œuvre. Comme MySQL ne dispose pas d’un environnement dédié pour la production
d’applications client/serveur, c’est souvent au travers de PHP qu’on la retrouve. Ce cha-
pitre vise à trouver un équilibre entre le monde SQL et le monde de la programmation
client/serveur. À l’issue de ce chapitre, vous serez capable :
 d’utiliser une classe PHP pour présenter une table MySQL au format HTML.
 de proposer des fonctions standard sur cette table en limitant le couplage
MySQL/HTML.
 d’optimiser les performances de lecture d’une table en fractionnant la présentation
en pages.
 de stocker dans une base MySQL des fichiers binaires et de les retrouver.
 de mettre en place un système de mapping objet/relationnel, très utile pour la réali-
sation d’applications distribuées.

$ Pré-requis
Pour valider les pré-requis nécessaires, avant d’aborder le TP, indiquez si les affir-
mations ci-après sont vraies ou fausses.
 MySQL est la seule base de données qui fonctionne avec PHP.
 MySQL ne fonctionne qu’avec PHP.
 MySQL ne fonctionne que sous Unix.
 PHPMyAdmin est indispensable pour administrer une base MySQL.
 MySQL ne connaît pas la notion de schéma.

© Editions ENI - Toute reproduction interdite


PHP 5 - MySQL 5 - Ajax
50
LES TP INFORMATIQUES

% Énoncé 4.1 : Création d’une classe PHP pour présenter


une table MySQL
Durée estimative : 45 minutes
Les programmeurs PHP écrivent continuellement les mêmes lignes pour obtenir
des résultats finalement très proches. Le scénario est si bien connu que l’on ga-
gne à les placer dans une classe plutôt que dans un simple fichier include. Cette
classe aide à opérer la distinction entre le domaine de la présentation HTML et
le domaine de la manipulation des bases de données.
Nous nous proposons de réaliser une telle classe pour présenter une table MySQL
et ses enregistrements au travers d’une page PHP. La classe contient des fonc-
tions indépendantes de la présentation telles que la suppression et l’exploration
détaillée d’enregistrements.

 Créez sous MySQL une base Guide et une table Restaurant contenant les
champs suivants :
Champ Type
id entier calculé automatiquement, clé primaire
nom texte
adresse texte
prix double

© Editions ENI - Toute reproduction interdite


Accès aux données MySQL 5 depuis PHP
51
ÉNONCÉS DU CHAPITRE 4

Champ Type
commentaires texte
note double
visite date
Insérez quelques enregistrements.
 Concevez une page PHP pour présenter les données sous forme tabulaire.
 Concevez une classe MyTable dans un fichier bases.php pour initialiser la
connexion et effectuer la requête select dans le constructeur, sans toutefois
afficher les données.
 Ajoutez une méthode rendre_html() à la classe pour afficher les données
sous forme tabulaire.
 Ajoutez une méthode info_table() pour extraire et copier dans un ta-
bleau PHP les noms des colonnes présentes dans le résultat de la requête.
 Modifiez la méthode rendre_html() pour faire figurer les noms des colon-
nes sur la première ligne.
 Modifiez la fonction info_table() pour déterminer le nom de la colonne
qui sert de clé primaire.
 Modifiez la méthode rendre_html() pour insérer un lien vers une URL para-
métrée pour chaque enregistrement (par exemple detail.php?id=34).

Indices pour l’énoncé 4.1


 Utilisez PHPMyAdmin.
 Reprenez l’exemple habituel, en prenant soin de ne pas trop imbriquer code
HTML et code PHP : adoptez le style de programmation "cgi".
 Il faut profiter du fait que l’on peut donner des paramètres au constructeur
pour le rendre le plus général possible.
 Il suffit de déplacer le code de la question 2 dans une fonction de la classe
MyTable.
 Consultez la documentation pour déterminer quelles fonctions de l’API PHP
vous donnent accès à ces informations.
 L’appel de la méthode info_table() sera fait dans le constructeur plutôt
que dans rendre_html().
 Même conseil que pour la question 5.

© Editions ENI - Toute reproduction interdite


PHP 5 - MySQL 5 - Ajax
52
LES TP INFORMATIQUES

 Le paramètre peut faire partie de l’URL pour être remplacé en utilisant les
expressions régulières. En général, on utilise une séquence telle que {0}.
Il est également possible de passer l’URL, le nom du paramètre et le champ
servant d’identifiant comme arguments à la méthode rendre_html(). La
programmation est alors plus simple.

& Énoncé 4.2 : Pour aller plus loin : suppression


d’enregistrements
Durée estimative : 20 minutes
Cet exercice sur la suppression d’enregistrements vous donnera des idées pour
finalement éditer toutes les colonnes de la table considérée.
MyTable
-$connexion
-$requete
-$result_set
-$table
-$base
-$colonnes_rc
-$colonnes
-$id
+MyTable()
+info_table()
+rendre_html()
+supprimer()

 Modifiez la méthode rendre_html() pour ajouter des boutons destinés à


supprimer un enregistrement.
 Ajoutez une méthode chargée d’interpréter les événements produits par ces
boutons.

Indices pour l’énoncé 4.2


 N’oubliez pas d’insérer un formulaire pour que vos boutons soient actifs. Ajou-
tez un champ caché pour passer l’identifiant de la ligne à supprimer. Ajoutez
également une fonction JavaScript chargée de remplir le champ caché et
de publier le formulaire.
 La fonction JavaScript a rempli un champ caché qui contient l’identifiant de
la ligne à supprimer. Il suffit de récupérer la valeur de ce champ côté PHP et
de procéder à la suppression.

© Editions ENI - Toute reproduction interdite


Accès aux données MySQL 5 depuis PHP
53
ÉNONCÉS DU CHAPITRE 4

' Énoncé 4.3 : Présentation paginée d’une table MySQL


Durée estimative : 40 minutes
Il est souvent nécessaire de fractionner la lecture et l’affichage d’enregistre-
ments issus d’une base de données, les performances et la lisibilité s’améliorent
alors nettement. La construction d’un dispositif permettant ce fractionnement est
l’objet de ce TP.

Peupler.php Annuaire.php

Annuaire

 Créez une base Annuaire à l’aide PHPMyAdmin ou d’un script sql, ainsi
qu’une table Personne contenant les champs ID (auto_increment), NOM
(text) et TELEPHONE (text).
 Créez un script peupler.php, non nécessairement sous la forme d’une page
web, chargé d’alimenter la table. Pour cela, préparez deux chaînes de ca-
ractères, l’une contenant des prénoms séparés par des virgules, l’autre avec
des noms de famille. Utilisez le découpage (split) pour générer des tableaux.
Utilisez ensuite une fonction de génération automatique de coordonnées, as-
sociant un prénom, un nom, et un numéro à 4 chiffres. Évitez les doublons.
Chaque entrée générée est insérée dans la base. Générez une centaine de
lignes.
 Construisez une page annuaire.php chargée de présenter l’intégralité des li-
gnes. Cherchez une solution très simple, très concise.
 Testez la vitesse d’exécution et proposez des améliorations.
Inutile d’afficher l’heure au dixième de seconde près.
 Utilisez des paramètres sur la chaîne d’interrogation (query string) pour
contrôler le nombre d’enregistrements présentés ainsi que l’enregistrement de
départ.

© Editions ENI - Toute reproduction interdite


PHP 5 - MySQL 5 - Ajax
54
LES TP INFORMATIQUES

 Estimez la différence d’exécution.


Il est toujours inutile d’afficher l’heure.

Indices pour l’énoncé 4.3


 Un script est plus difficile à mettre au point mais il peut resservir. Pour faire
fonctionner un script, utilisez la ligne de commande mysql :
mysql -u root -h localhost < script.txt
 Il n’est pas nécessaire de créer une page web : la mise au point du jeu de
données est une opération unitaire, elle ne concerne qu’une seule personne,
l’administrateur (ou le formateur). Ainsi on ne perd pas de temps avec des
détails de mise en forme HTML.
 Travaillez sur la requête SQL en fonction des paramètres. Pensez à donner des
valeurs par défaut aux paramètres.

© Editions ENI - Toute reproduction interdite


Editions ENI

PHP 5.2
Développer un site Web
dynamique et interactif

dans la collection
Ressources Informatiques

Extrait
&KDSLWUH

$ 9XHG¶HQVHPEOH
 3HWLWUDSSHOVXUOHVIRUPXODLUHV
/H IRUPXODLUH HVW XQ RXWLO GH EDVH LQGLVSHQVDEOH SRXU OHV VLWHV :HE G\QDPLTXHV SXLVTX·LO
SHUPHW j O·XWLOLVDWHXU GH VDLVLU GHV LQIRUPDWLRQV HW GRQF G·LQWHUDJLU DYHF OH VLWH
8Q IRUPXODLUH +70/ HVW GpILQL HQWUH OHV EDOLVHV <FORM> HW </FORM>

<FORM
[ ACTION="url_de_traitement" ]
[ METHOD="GET"|"POST" ]
[ NAME="nom_formulaire" ]
>
...
</FORM>
/HV RSWLRQV GH OD EDOLVH <FORM> VRQW OHV VXLYDQWHV 
ACTION 85/ UHODWLYH RX DEVROXH 
      TXL YD WUDLWHU OH IRUPX
ODLUH HQ FH TXL QRXV FRQFHUQH XQ VFULSW 3+3 6L ULHQ Q·HVW VSpFLILp OD PrPH
85/ TXH OD SDJH HVW XWLOLVpH
METHOD 0RGH GH WUDQVPLVVLRQ YHUV OH VHUYHXU GHV LQIRUPDWLRQV VDLVLHV GDQV OH IRUPX
ODLUH
*(7 YDOHXU SDU GpIDXW  OHV GRQQpHV GX IRUPXODLUH VRQW WUDQVPLVHV GDQV O·85/
3267  OHV GRQQpHV GX IRUPXODLUH VRQW WUDQVPLVHV GDQV OH FRUSV GH OD UHTXrWH
NAME 1RP GX IRUPXODLUH 6L OD SDJH +70/ FRQWLHQW SOXVLHXUV IRUPXODLUHV OH QRP
SHUPHW GH OHV GLIIpUHQFLHU (Q FH TXL QRXV FRQFHUQH FH QRP QH SUpVHQWH SDV
G·LQWpUrW FDU LO Q·HVW SDV UpFXSpUp GDQV OH VFULSW GH WUDLWHPHQW GX IRUPXODLUH
3DU FRQWUH LO SHXW rWUH XWLOLVp F{Wp FOLHQW HQ -DYD6FULSW SDU H[HPSOH
(QWUH OHV EDOLVHV <FORM> HW </FORM> LO HVW SRVVLEOH GH SODFHU GHV EDOLVHV <INPUT>,
<SELECT> RX <TEXTAREA> SRXU GpILQLU GHV ]RQHV GH VDLVLHV
  
    
<FORM>
Nom :
<INPUT TYPE="text" NAME="nom" VALUE=""
SIZE="20" MAXLENGTH="20">
Mot de passe :
<INPUT TYPE="password" NAME="mot_de_passe" VALUE=""
SIZE="20" MAXLENGTH="20">
<BR>Sexe :
<INPUT TYPE="radio" NAME="sexe" VALUE="M"> Masculin
<INPUT TYPE="radio" NAME="sexe" VALUE="F"> Féminin
<INPUT TYPE="radio" NAME="sexe" VALUE="?"
CHECKED> Ne sait pas
<BR>Photo :
<INPUT TYPE="file" NAME="photo" VALUE="" SIZE="50">
<BR>Couleurs préférées :
<INPUT TYPE="checkbox" NAME="bleu"> Bleu
<INPUT TYPE="checkbox" NAME="blanc"> Blanc
<INPUT TYPE="checkbox" NAME="rouge"> Rouge

 3+3
*HVWLRQGHVIRUPXODLUHV

<INPUT TYPE="checkbox" NAME="nesaitpas" CHECKED> Ne sait pas


<BR>Langue :
<SELECT NAME="langue">
<OPTION VALUE="E">Espagnol
<OPTION SELECTED VALUE="F">Français
<OPTION VALUE="I">Italien
</SELECT>
<BR>Fruits préférés :<BR>
<SELECT NAME="fruits" MULTIPLE SIZE="8">
<OPTION VALUE="A">Abricots
<OPTION VALUE="C">Cerises
<OPTION VALUE="F">Fraises
<OPTION VALUE="P">Pêches
<OPTION SELECTED VALUE="?">Ne sait pas
</SELECT>
<BR>Commentaire :<BR>
<TEXTAREA NAME="commentaire" ROWS="4" COLS="50"></TEXTAREA>
<BR>
<INPUT TYPE="hidden" NAME="invisible" VALUE="123"><BR>
<INPUT TYPE="submit" NAME="OK" VALUE="OK">
<INPUT TYPE="image" NAME="valider"
SRC="valider.gif" WIDTH="23" HEIGHT="34">
<INPUT TYPE="reset" NAME="effacer" VALUE="Effacer">
<INPUT TYPE="button" NAME="action" VALUE="Ne fait rien">
</FORM>
© (GLWLRQV (1,  $OO ULJKWV UHVHUYHG



'pYHORSSHUXQVLWH:HEG\QDPLTXHHWLQWHUDFWLI 
&KDSLWUH

 ,QWHUDFWLRQHQWUHXQIRUPXODLUHHWXQVFULSW3+3
3+3 SHXW LQWHUYHQLU j GHX[ HQGURLWV SDU UDSSRUW DX IRUPXODLUH 
- SRXU OD FRQVWUXFWLRQ GX IRUPXODLUH VL FH GHUQLHU GRLW FRQWHQLU GHV LQIRUPDWLRQV
G\QDPLTXHV 
- SRXU OH WUDLWHPHQW GX IRUPXODLUH F·HVWjGLUH GHV GRQQpHV VDLVLHV SDU O·XWLOLVDWHXU GDQV OH
IRUPXODLUH 
7URLV JUDQGHV PpWKRGHV VRQW XWLOLVDEOHV SRXU IDLUH LQWHUDJLU XQ IRUPXODLUH HW XQ VFULSW 3+3 
- SODFHU OH IRUPXODLUH GDQV XQ GRFXPHQW +70/ SXU .htm RX .html  OH IRUPXODLUH QH
FRQWLHQW DORUV DXFXQ pOpPHQW G\QDPLTXH HW LQGLTXHU OH QRP GX VFULSW 3+3 TXL GRLW
WUDLWHU OH IRUPXODLUH GDQV O·RSWLRQ ACTION GH OD EDOLVH <FORM> 
- SODFHU OH IRUPXODLUH GDQV XQ VFULSW 3+3 SDU H[HPSOH SRXU FRQVWUXLUH XQH SDUWLH GX
IRUPXODLUH G\QDPLTXHPHQW HW IDLUH WUDLWHU OH IRUPXODLUH SDU XQ DXWUH VFULSW 3+3
PHQWLRQQp GDQV O·RSWLRQ ACTION GH OD EDOLVH <FORM> 
- SODFHU OH IRUPXODLUH GDQV XQ VFULSW 3+3 SDU H[HPSOH SRXU FRQVWUXLUH XQH SDUWLH GX
IRUPXODLUH G\QDPLTXHPHQW  HW OH IDLUH WUDLWHU SDU OH PrPH VFULSW 3+3 PHQWLRQQp GDQV
O·RSWLRQ ACTION GH OD EDOLVH <FORM> RX DSSHOp SDU GpIDXW VL FHWWH RSWLRQ Q·HVW SDV
SUpVHQWH 
    

      
<HTML>
<HEAD><TITLE>Saisie</TITLE></HEAD>
<BODY>
<FORM ACTION="traitement.php" METHOD="POST">
Nom : <INPUT TYPE="text" NAME="nom" VALUE=""><BR>
<INPUT TYPE="submit" NAME="OK" VALUE="OK">
</FORM>
</BODY>
</HTML>
   traitement.php
<?php
/* A faire ...
- récupérer les informations saisies
- faire le traitement
- afficher une nouvelle page
*/
?>
3DU DLOOHXUV VXU XQH DXWUH SDJH XQ OLHQ 6DLVLH SDU H[HPSOH SHXW rWUH LQVpUp SRXU DSSHOHU
OH IRUPXODLUH GH VDLVLH 
<A HREF="saisie.htm">Saisie</A>

 3+3
*HVWLRQGHVIRUPXODLUHV


- $IILFKDJH LQLWLDO GX IRUPXODLUH 

- 6DLVLH G·XQH LQIRUPDWLRQ 

- /H UpVXOWDW GX FOLF VXU OH ERXWRQ  HVW XQH SDJH YLGH FDU SRXU O·LQVWDQW OH VFULSW GH
WUDLWHPHQW QH IDLW ULHQ
     

      
8Q SHX GH FRGH 3+3 HQ JUDV HVW XWLOLVp SRXU JpQpUHU OD SDUWLH G\QDPLTXH GX IRUPXODLUH
<?php
// inclure un fichier qui contient des définitions de
// constantes, dont le titre de la page (TITRE_PAGE_SAISIE)
require("constantes.inc");
// initialisation d’une variable qui contient la valeur
// initiale de la zone de saisie (dans la pratique, cette
// valeur vient sans doute d’ailleurs et n’est pas codée
// en dur)
$nom = "X";
// dans le code HTML qui suit, inclusion de deux petits
// bouts de code PHP pour afficher respectivement le titre
// de la page et la valeur initiale de la zone de saisie
?>
<HTML>
<HEAD><TITLE><?php echo TITRE_PAGE_SAISIE ?></TITLE></HEAD>
<BODY>
<FORM ACTION="traitement.php" METHOD="POST">
Nom : <INPUT TYPE="text" NAME="nom"
VALUE="<?php echo $nom ?>"><BR>
<INPUT TYPE="submit" NAME="OK" VALUE="OK">
</FORM>
</BODY>
</HTML>
   traitement.php
© (GLWLRQV (1,  $OO ULJKWV UHVHUYHG

<?php
/* A faire ...
- récupérer les informations saisies
- faire le traitement
- afficher une nouvelle page
*/
?>

'pYHORSSHUXQVLWH:HEG\QDPLTXHHWLQWHUDFWLI 
&KDSLWUH

3DU DLOOHXUV VXU XQH DXWUH SDJH XQ OLHQ 6DLVLH SDU H[HPSOH SHXW rWUH LQVpUp SRXU DSSHOHU
OH IRUPXODLUH GH VDLVLH 
<A HREF="saisie.php">Saisie</A>

- $IILFKDJH LQLWLDO GX IRUPXODLUH XQH YDOHXU LQLWLDOH G\QDPLTXH HVW SURSRVpH SRXU OD ]RQH
GH VDLVLH 

- 6DLVLH G·XQH LQIRUPDWLRQ 

- /H UpVXOWDW GX FOLF VXU OH ERXWRQ  HVW XQH SDJH YLGH FDU SRXU O·LQVWDQW OH VFULSW GH
WUDLWHPHQW QH IDLW ULHQ
     

    saisie.php
&·HVW OH PrPH VFULSW TXH SUpFpGHPPHQW GDQV OHTXHO QRXV DYRQV VLPSOHPHQW FKDQJp O·RS
WLRQ ACTION GH OD EDOLVH <FORM> SRXU LQGLTXHU TXH OH IRUPXODLUH GRLW rWUH WUDLWp SDU OH
PrPH VFULSW saisie.php QH SDV PHWWUH G·RSWLRQ ACTION DXUDLW OH PrPH HIIHW 
<?php
// inclure un fichier qui contient des définitions de
// constantes, dont le titre de la page (TITRE_PAGE_SAISIE)
require("constantes.inc");
// initialisation d’une variable qui contient la valeur
// initiale de la zone de saisie (dans la pratique, cette
// valeur vient sans doute d’ailleurs et n’est pas codée en dur)
$nom = "X";
// dans le code HTML qui suit, inclusion de deux petits
// bouts de code PHP pour afficher respectivement le titre
// de la page et la valeur initiale de la zone de saisie
?>
<HTML>
<HEAD><TITLE><?php echo TITRE_PAGE_SAISIE ?></TITLE></HEAD>
<BODY>
<FORM ACTION="saisie.php" METHOD="POST">
Nom : <INPUT TYPE="text" NAME="nom"
VALUE="<?php echo $nom ?>"><BR>
<INPUT TYPE="submit" NAME="OK" VALUE="OK">
</FORM>
</BODY>
</HTML>
3DU DLOOHXUV VXU XQH DXWUH SDJH XQ OLHQ 6DLVLH SDU H[HPSOH SHXW rWUH LQVpUp SRXU DSSHOHU
OH IRUPXODLUH GH VDLVLH 
<A HREF="saisie.php">Saisie</A>

 3+3
*HVWLRQGHVIRUPXODLUHV


- $IILFKDJH LQLWLDO GX IRUPXODLUH XQH YDOHXU LQLWLDOH G\QDPLTXH HVW SURSRVpH SRXU OD ]RQH
GH VDLVLH 

- 6DLVLH G·XQH LQIRUPDWLRQ 

- /H UpVXOWDW GX FOLF VXU OH ERXWRQ  HVW OD PrPH SDJH GH QRXYHDX DIILFKpH FDU SRXU
O·LQVWDQW OH VFULSW GH WUDLWHPHQW QH IDLW ULHQ GH SOXV

! "#   $


/H VFULSW saisie.php D pWp DSSHOp GH QRXYHDX SDU OH FOLF VXU OH ERXWRQ   LO V·HVW GRQF
H[pFXWp FRPPH ORUV GH VRQ SUHPLHU DSSHO OLHQ 6DLVLH  &RPPH OH FRGH QH IDLW ULHQ SRXU
O·LQVWDQW DILQ GH WUDLWHU OH IRUPXODLUH LO V·DIILFKH FRPPH LQLWLDOHPHQW 8WLOLVHU OH PrPH VFULSW
SRXU O·DIILFKDJH LQLWLDO HW OH WUDLWHPHQW QpFHVVLWH G·rWUH HQ PHVXUH GH IDLUH OD GLIIpUHQFH HQWUH
OHV GHX[ W\SHV G·DSSHOV FI %   /HV GLIIpUHQWV W\SHV GH ]RQHV 
 

/H FKRL[ GH WHOOH RX WHOOH PpWKRGH GpSHQG GH OD FRPSOH[LWp GX VLWH HW GHV SUpIpUHQFHV GH
FKDFXQ
4XHOTXHV FRQVLGpUDWLRQV JpQpUDOHV 
- 6pSDUHU OD SDJH +70/ RX OH VFULSW 3+3 TXL JpQqUH OH IRUPXODLUH GX VFULSW 3+3
SUpVHQWH XQ LQFRQYpQLHQW DX QLYHDX GH OD PDLQWHQDQFH  VL GHV PRGLILFDWLRQV VRQW
DSSRUWpHV DX IRUPXODLUH LO \ D GHX[ ILFKLHUV j PRGLILHU DYHF GHV ULVTXHV G·HUUHXU
G·RXEOL 
- ,QYHUVHPHQW VL OH IRUPXODLUH Q·D DXFXQH SDUWLH G\QDPLTXH O·pFULUH GDQV XQ ILFKLHU +70/
VpSDUp GX VFULSW 3+3 TXL OH WUDLWH SHUPHW GH ELHQ VpSDUHU O·LQWHUIDFH XWLOLVDWHXU OD
FRXFKH SUpVHQWDWLRQ GX WUDLWHPHQW
© (GLWLRQV (1,  $OO ULJKWV UHVHUYHG

- 'DQV OD SUDWLTXH SRXU IDFLOLWHU OD PDLQWHQDQFH LO HVW VRXKDLWDEOH GH GpILQLU FHUWDLQHV


YDOHXUV SUpVHQWpHV j SOXVLHXUV UHSULVHV QRP GH VRFLpWp SDU H[HPSOH GDQV GHV FRQVWDQWHV
RX GHV YDULDEOHV HW G·XWLOLVHU FHV FRQVWDQWHVYDULDEOHV GDQV OHV SDJHV  WRXWHV OHV SDJHV
GHYLHQQHQW XQ SHX G\QDPLTXHV HW OD WURLVLqPH PpWKRGH SDUDvW RSWLPDOH
'DQV OD VXLWH GH FH FKDSLWUH QRXV DOORQV UHQWUHU GDQV OH GpWDLO GX WUDLWHPHQW GX IRUPXODLUH
HQ 3+3 HQ XWLOLVDQW GHV H[HPSOHV FRQVWUXLWV VXU OH PRGqOH GH OD WURLVLqPH PpWKRGH

'pYHORSSHUXQVLWH:HEG\QDPLTXHHWLQWHUDFWLI 

Vous aimerez peut-être aussi