Pour le script PHP exécuté par le serveur, cela correspond aux deux instructions suivantes : $genre[] = ’H’; $genre[] = ’S’;... Mieux : PHP incrémente automatiquement l’indice pour chaqu
Trang 1H i s t o i r e : < i n p u t t y p e = ’ checkbox ’ name = ’ g e n r e [ ] ’ v a l u e = ’H ’ / >
S u s p e n s e : < i n p u t t y p e = ’ checkbox ’ name = ’ g e n r e [ ] ’ v a l u e = ’ S ’ / >
< / p><p>
F r a n c e : < i n p u t t y p e = ’ r a d i o ’ name = ’ p a y s ’ v a l u e = ’ FR ’
c h e c k e d = ’ 1 ’ / >
E t a t s−Unis : <i n pu t type = ’ r a d i o ’ name= ’ pays ’ v a l u e = ’US ’ / >
A l l e m a g n e : < i n p u t t y p e = ’ r a d i o ’ name = ’ p a y s ’ v a l u e = ’DE ’ / >
J a p o n : < i n p u t t y p e = ’ r a d i o ’ name = ’ p a y s ’ v a l u e = ’ JP ’ / >
< / p>
<p>
M e t t e u r en s c è n e ( prénom − nom) :
< i n p u t t y p e = ’ t e x t ’ s i z e = ’ 2 0 ’ name= " prenom " / >
< i n p u t t y p e = ’ t e x t ’ s i z e = ’ 2 0 ’ name= " nom " > < b r / >
Année de n a i s s a n c e : < i n p u t t y p e = ’ t e x t ’ s i z e = ’ 4 ’ m a x l e n g t h = ’ 4 ’
name= " a n n e e _ n a i s s a n c e " v a l u e = ’ 2 0 0 0 ’ / >
< / p>
Résumé : < t e x t a r e a name = ’ r e s u m e ’ c o l s = ’ 3 0 ’ rows = ’ 3 ’ >Résumé du
f i l m
< / t e x t a r e a >
<h1> V o t r e c h o i x < / h1>
< i n p u t t y p e = ’ s u b m i t ’ v a l u e = ’ I n s é r e r ’ name = ’ i n s e r e r ’ / >
< i n p u t t y p e = ’ s u b m i t ’ v a l u e = ’ M o d i f i e r ’ name = ’ m o d i f i e r ’ / >
< i n p u t t y p e = ’ s u b m i t ’ v a l u e = ’ D é t r u i r e ’ name = ’ d e t r u i r e ’ / >
< i n p u t t y p e = ’ r e s e t ’ v a l u e = ’ Annuler ’ / >
< / form>
< / body>
< / html>
Il est assez proche de celui de l’exemple 1.2, page 13, avec quelques différences notables Tout d’abord, le nom du champ genre est genre[].
Comédie : < i n p u t t y p e = ’ checkbox ’ name = ’ g e n r e [ ] ’ v a l u e = ’C ’ / >
Drame : < i n p u t t y p e = ’ checkbox ’ name = ’ g e n r e [ ] ’ v a l u e = ’D ’ / >
H i s t o i r e : < i n p u t t y p e = ’ checkbox ’ name = ’ g e n r e [ ] ’ v a l u e = ’H ’ / >
S u s p e n s e : < i n p u t t y p e = ’ checkbox ’ name = ’ g e n r e [ ] ’ v a l u e = ’ S ’ / >
Pour comprendre l’utilité de cette notation, il faut se souvenir que les paramètres issus du formulaire sont passés au script sur le serveur sous la forme de paires
nom=valeur Ici on utilise un champ checkbox puisqu’on peut affecter plusieurs
genres à un film Si on clique sur au moins deux des valeurs proposées, par exemple
« Histoire » et « Suspense », la chaîne transmise au serveur aura la forme suivante : .&genre[]=H&genre[]=S&
Pour le script PHP exécuté par le serveur, cela correspond aux deux instructions suivantes :
$genre[] = ’H’;
$genre[] = ’S’;
Trang 2Imaginons un instant que l’on utilise un nom de variable $genre, sans les crochets [] Alors pour PHP la deuxième affectation viendrait annuler la première
et $genre n’aurait qu’une seule valeur, ’S’ La notation avec crochets indique que
$genre est en fait un tableau, donc une liste de valeurs Mieux : PHP incrémente
automatiquement l’indice pour chaque nouvelle valeur placée dans un tableau Les deux instructions ci-dessus créent un tableau avec deux entrées, indicées respective-ment par 0 et 1, et stockant les deux valeurs ’H’ et ’S’.
Une autre particularité du formulaire est l’utilisation de plusieurs boutons submit, chacun associé à un nom différent.
< i n p u t t y p e = ’ s u b m i t ’ v a l u e = ’ I n s é r e r ’ name = ’ i n s e r e r ’ / >
< i n p u t t y p e = ’ s u b m i t ’ v a l u e = ’ M o d i f i e r ’ name = ’ m o d i f i e r ’ / >
< i n p u t t y p e = ’ s u b m i t ’ v a l u e = ’ D é t r u i r e ’ name = ’ d e t r u i r e ’ / >
Quand l’utilisateur clique sur l’un des boutons, une seule variable PHP est créée, dont le nom correspond à celui du bouton utilisé Le script peut tirer parti de ce mécanisme pour déterminer le type d’action à effectuer.
Le script PHP
La troisième composante de cette application de mise à jour est le script PHP.
Exemple 1.13 exemples/ExMyPHP3.php:Le script de mise à jour de FilmComplet
<? xml v e r s i o n = " 1 0 " e n c o d i n g = " i s o−8959−1 " ? >
<!DOCTYPE html PUBLIC "−//W3C/ / DTD XHTML 1 0 S t r i c t / / EN"
" h t t p : / / www w3 o r g / TR / xhtml1 /DTD/ xhtml1−s t r i c t dtd ">
<html xmlns= " h t t p : / / www w3 o r g / 1 9 9 9 / xhtml " xml : l a n g = " f r " >
<head >
< t i t l e > R é s u l t a t de l a m i s e à j o u r < / t i t l e >
< l i n k r e l = ’ s t y l e s h e e t ’ h r e f = " f i l m s c s s " t y p e = " t e x t / c s s " / >
</ head >
<body >
<h1> R é s u l t a t de l a m i s e à j o u r p a r f o r m u l a i r e < / h1>
<? php
r e q u i r e ( " Connect php " ) ;
/ / R é c u p é r a t i o n d e s v a r i a b l e s
/ / Q u e l q u e s c o n t r ô l e s s e r a i e n t n é c e s s a i r e s
$ t i t r e = $_POST [ ’ t i t r e ’ ] ;
$annee = $_POST [ ’ annee ’ ] ;
$ p a y s = $_POST [ ’ p a y s ’ ] ;
$prenom = $_POST [ ’ prenom ’ ] ;
$ a n n e e _ n a i s s a n c e = $_POST [ ’ a n n e e _ n a i s s a n c e ’ ] ;
$ r e s u m e = $_POST [ ’ r e s u m e ’ ] ;
Trang 3/ / I l p e u t n ’ y a v o i r a u c u n g e n r e s a i s i
i f ( ! i s S e t ( $_POST [ ’ g e n r e ’ ] ) )
$ g e n r e = a r r a y ( ) ;
e l s e
$ g e n r e = $_POST [ ’ g e n r e ’ ] ;
echo " < h r / > <h2>\n " ;
/ / T e s t du t y p e d e l a m i s e à j o u r e f f e c t u é e
i f ( i s S e t ( $_POST [ ’ i n s e r e r ’ ] ) )
echo " I n s e r t i o n du f i l m $ t i t r e " ;
e l s e i f ( i s S e t ( $_POST [ ’ m o d i f i e r ’ ] ) )
echo " M o d i f i c a t i o n du f i l m $ t i t r e " ;
e l s e i f ( i s S e t ( $_POST [ ’ d e t r u i r e ’ ] ) )
echo " D e s t r u c t i o n du f i l m $ t i t r e " ;
echo " </ h2>< h r / >\n " ;
/ / A f f i c h a g e d e s d o n n é e s du f o r m u l a i r e
echo " T i t r e : $ t i t r e < b r / > annee : $annee < b r / > P a y s : $ p a y s < b r / >\n " ;
/ / P r é p a r a t i o n d e l a c h a î n e p o u r i n s é r e r
$ c h a i n e _ g e n r e = " " ; $ s e p a r a t e u r = " " ;
f o r ( $ i = 0 ; $ i < c o u n t ( $ g e n r e ) ; $ i ++) {
$ c h a i n e _ g e n r e = $ s e p a r a t e u r $ g e n r e [ $ i ] ;
$ s e p a r a t e u r = " , " ;
}
echo " G e n r e s = $ c h a i n e _ g e n r e < b r / > " ;
echo " Résumé = $ r e s u m e < b r / >\n " ;
echo " Mis en s c è n e p a r $prenom $nom\n " ;
/ / C o n n e x i o n à l a b a s e , e t c r é a t i o n d e l ’ o r d r e SQL
$ c o n n e x i o n = m y s q l _ p c o n n e c t (SERVEUR , NOM, PASSE ) ;
m y s q l _ s e l e c t _ d b (BASE , $ c o n n e x i o n ) ;
i f ( i s S e t ( $_POST [ ’ i n s e r e r ’ ] ) )
$ r e q u e t e = " INSERT INTO F i l m C o m p l e t ( t i t r e , annee , "
" p r e n o m _ r e a l i s a t e u r , n o m _ r e a l i s a t e u r , a n n e e _ n a i s s a n c e , " " p a y s , g e n r e , r e s u m e ) VALUES ( ’ $ t i t r e ’ , $annee , "
" ’ $prenom ’ , ’ $nom ’ , $ a n n e e _ n a i s s a n c e , "
" ’ $ p a y s ’ , ’ $ c h a i n e _ g e n r e ’ , ’ $ r e s u m e ’ ) " ;
i f ( i s S e t ( $_POST [ ’ m o d i f i e r ’ ] ) )
$ r e q u e t e = "UPDATE F i l m C o m p l e t SET annee=$annee , "
" p r e n o m _ r e a l i s a t e u r = ’ $prenom ’ , n o m _ r e a l i s a t e u r = ’ $nom ’ , " " a n n e e _ n a i s s a n c e = $ a n n e e _ n a i s s a n c e , p a y s = ’ $ p a y s ’ , "
" g e n r e = ’ $ c h a i n e _ g e n r e ’ , r e s u m e = ’ $ r e s u m e ’ "
" WHERE t i t r e = ’ $ t i t r e ’ " ;
Trang 4i f ( i s S e t ( $_POST [ ’ d e t r u i r e ’ ] ) )
$ r e q u e t e = " DELETE FROM F i l m C o m p l e t WHERE t i t r e = ’ $ t i t r e ’ " ;
/ / E x é c u t i o n d e l ’ o r d r e SQL ( un t e s t d ’ e r r e u r s e r a i t b i e n v e n u )
$ r e s u l t a t = m y s q l _ q u e r y ( $ r e q u e t e , $ c o n n e x i o n ) ;
i f ( $ r e s u l t a t )
echo " < h r / > La r e q u ê t e ’ $ r e q u e t e ’ a é t é e f f e c t u é e \ n " ;
e l s e {
echo " La r e q u ê t e n ’ a pu ê t r e e x é c u t é e p o u r l a r a i s o n s u i v a n t e : " m y s q l _ e r r o r ( $ c o n n e x i o n ) ;
}
? >
</ body >
</ html >
Ce script procède en plusieurs étapes, chacune donnant lieu à une insertion dans
la page HTML fournie en retour au serveur.
Tout d’abord, on récupère les paramètres transmis en principe par le formulaire.
En pratique rien ne garantit, encore une fois, qu’un utilisateur malicieux ne va pas appeler le script sans utiliser le formulaire et sans même passer un paramètre Il faudrait tester l’existence des paramètres attendus, si la sécurité était importante Ce test peut être effectué avec la fonction isSet(), et un exemple est ici donné pour le paramètre genre :
/ / I l p e u t n ’ y a v o i r a u c u n g e n r e s a i s i
i f ( ! i s S e t ( $_POST [ ’ g e n r e ’ ] ) )
$ g e n r e = a r r a y ( ) ;
e l s e
$ g e n r e = $_POST [ ’ g e n r e ’ ] ;
Si on constate qu’aucun genre n’est transmis (ce qui peut arriver même si l’on utilise le formulaire puisque ce dernier ne comprend pas de contrôles), on initialise
la variable $genre avec un tableau vide (array()) Ce type de contrôle pourrait/de-vrait être effectué pour tous les paramètres : c’est fastidieux mais souvenez-vous qu’un script est un programme en accès libre pour le monde entier
On contrôle ensuite le bouton de déclenchement utilisé Selon le cas, on trouve
un élément ’inserer’, ’modifier’, ou ’detruire’ dans le tableau $_POST, et on
en déduit le type de mise à jour effectué On l’affiche alors pour informer l’utilisateur que sa demande a été prise en compte On utilise encore la fonction isSet() de PHP pour tester l’existence d’une variable (ici une entrée dans un tableau).
i f ( i s S e t ( $_POST [ ’ i n s e r e r ’ ] ) )
echo " I n s e r t i o n du f i l m $ t i t r e " ;
e l s e i f ( i s S e t ( $_POST [ ’ m o d i f i e r ’ ] ) )
echo " M o d i f i c a t i o n du f i l m $ t i t r e " ;
e l s e i f ( i s S e t ( $_POST [ ’ d e t r u i r e ’ ] ) )
echo " D e s t r u c t i o n du f i l m $ t i t r e " ;
Trang 5La construction if-elseif permet de contrơler successivement les différentes valeurs possibles On pourrait aussi utiliser une structure switch, ce qui permettrait
en outre de réagir au cas ó aucune des variables ci-dessus n’est définie.
On récupère ensuite les valeurs provenant du formulaire et on les affiche La variable $genre est traitée de manière particulière.
$ c h a i n e _ g e n r e = " " ; $ s e p a r a t e u r = " " ;
f o r ( $ i = 0 ; $ i < c o u n t ( $ g e n r e ) ; $ i ++) {
$ c h a i n e _ g e n r e = $ s e p a r a t e u r $ g e n r e [ $ i ] ;
$ s e p a r a t e u r = " , " ;
}
echo " G e n r e s = $ c h a i n e _ g e n r e < b r / > " ;
Notez l’initialisation des variables $chaine_genre et $separateur PHP peut parfois se montrer assez laxiste et accepter l’utilisation de variables non déclarées, en leur donnant alors la valeur 0 ou la chaỵne vide selon le contexte On peut envisager d’en tirer parti, mais dans certaines configurations – de plus en plus courantes – le niveau de contrơle (défini par l’option error_reporting dans le fichier de configu-ration) est très élevé et ce genre de pratique engendre des messages d’avertissement très désagréables Mieux vaut donc prendre l’habitude d’initialiser les variables Rappelons que $genre est un tableau, dont chaque élément correspond à un des choix de l’utilisateur La fonction count() permet de connaỵtre le nombre d’éléments, puis la boucle for est utilisée pour parcourir un à un ces éléments.
Au passage, on crée la variable $chaine_genre, une chaỵne de caractères qui contient la liste des codes de genres, séparés par des virgules, selon le format attendu par MySQL Si, par exemple, on a choisi « Histoire » et « Suspense »
$chaine_genre contiendra "H,S".
Enfin on construit la requête INSERT, UPDATE ou DELETE selon le cas.
Discussion
Le script précédent a beaucoup de défauts qui le rendent impropre à une véritable utilisation Une première catégorie de problèmes découle de la conception de la base
de données elle-même Il est par exemple possible d’insérer plusieurs fois le même film, une mise à jour peut affecter plusieurs films, il faut indiquer à chaque saisie l’année de naissance du metteur en scène même s’il figure déjà dans la base, etc Nous décrirons dans le chapitre 4 une conception plus rigoureuse qui permet d’éviter ces problèmes.
Si on se limite à la combinaison HTML/PHP en laissant pour l’instant de cơté la base MySQL, les faiblesses du script sont de deux natures.
Pas de contrơles Aucun test n’est effectué sur les valeurs des données, et en
par-ticulier des chaỵnes vides peuvent être transmises pour tous les champs De plus,
la connexion à MySQL et l’exécution des requêtes peuvent échouer pour des quantités de raisons : cet échec éventuel devrait être contrơlé.