TP PHP : Bases de données et interfaces web

publicité
TP PHP : Bases de données et interfaces web
Nicolas Moyroud
18 juin 2008
1 Présentation générale du TP
1.1
Contexte et objectifs du TP
Avec le langage PHP, vous allez réaliser des interfaces web qui vont permettre d'acher et de gérer des données
dans la base PostgreSQL. Les programmes developpés devront suivre une architecture respectant la séparation
entre les couches d'accès aux données et de présentation. Vous allez commencer par créer un programme qui
ache le contenu d'une table puis de toutes les tables de la base dans une page HTML. Vous réutiliserez ensuite
la partie présentation de ce programme pour acher le résultat d'une requête qui porte sur plusieurs tables.
Dans la dernière partie, vous allez réaliser des interfaces web qui proposent des formulaires pour la saisie et la
suppression de données dans les tables.
1.2
1.3
Principales étapes à réaliser
récupérer les enregistrements dans une table,
acher les données dans une page HTML,
exécuter une requête multi-tables et acher le résultat,
créer un formulaire de saisie de données,
ajouter une fonction de suppression des données.
Matériel et logiciels nécessaires
On dispose pour ce travail :
d'un PC sous Windows,
d'un serveur web Apache local avec son module PHP activé (WampServer),
du SGBD PostgreSQL et son interface d'administration phpPgAdmin.
1.4
Données fournies
Toutes les données manipulées sont contenues dans une base de données PostgreSQL.
1
2 Achage du contenu des tables de la base
Vous allez réaliser un programme PHP qui parcours une table de la base et ache les données sur une
interface web. Vous séparerez la couche d'accès et la couche de présentation des données. Pour nir, vous écrirez
un code générique capable d'acher les enregistrements contenus dans n'importe quelle table de la base.
Démarche
Vériez le serveur et
créez un nouveau
dossier
Ecrivez un code de
connexion à la base
PostgreSQL
Manipulation
Vériez que les services de Wampserver sont toujours actifs. Si ce n'est pas le cas,
démarrez les. Avec l'explorateur de chiers, ouvrez le répertoire C:\wamp\www\ird
et ajoutez y un sous-répertoire ihm. Pour toute la suite de ce TP, vous
travaillerez dans ce dossier. Ouvrez l'éditeur de code Notepad++ (Tous les
Programmes>Notepad++>Notepad++ ) et créez y un nouveau chier.
Ecrivez un code PHP qui lance une connexion à la base grâce à la fonction
pg_connect et stocke la connexion dans une variable $dbconn. Vous gèrerez les cas
d'erreurs avec un message. Sauvegardez le chier avec le nom connectDB.php. Voici
ce que vous devriez obtenir :
php
$dbconn
<?
if
=
pg_connect
(
' host = localhost dbname = isotopes
user = postgres password = postgres ' ) ;
( ! $dbconn ) {
echo ' Erreur de connexion ' ;
exit ;
}
?>
Exécutez une requête
SQL avec PHP
Ecrivez une requête SQL de sélection des enregistrements de la table Peche. Exécutez la avec PHP dans votre base de données PostgreSQL, en utilisant la fonction
pg_query. Vous récupèrerez le résultat de la requête dans une variable $result. Sauvegardez le chier avec le nom tableDAO.php. Voici ce que vous devriez obtenir :
$requete
=
" SELECT * FROM peche " ;
$result = pg_query ( $dbconn , $requete ) ;
if ( ! $result ) {
echo ' Erreur de requete ' ;
exit ;
}
Chargez les noms des
champs renvoyés
Dans le même chier, ajoutez un code qui parcours la variable $result pour charger les
noms des champs renvoyés dans un tableau PHP $eldsName (utilisez les fonctions
pg_num_elds et pg_eld_name) :
$num_fields = pg_num_fields ( $result ) ;
for ( $col = 0 ; $col < $num_fields ; $col ++) {
$fieldsName [ ] = pg_field_name ( $result , $col ) ;
}
2
Achez les données
dans une page HTML
Vous allez maintenant créer la couche de présentation qui ache dans une page
HTML les données récupérées à l'étape précédente. Créez un nouveau chier
printData.php et parcourez la variable $result avec la fonction pg_fetch_row pour
créer une table HTML. Vous utiliserez le tableau PHP $eldsName pour achez sur
la première ligne les noms des colonnes. En-dessous de la table HTML, vous indiquerez le nombre d'enregistrements achés en utilisant la fonction pg_num_rows.
html ><head ></head >
body >
< table border="1" cellspacing="0"><tr><th>
<? php
echo implode ( ' </th >< th > ' , $fieldsName ) ;
echo ' </th > </ tr > ' ;
while ( $row = pg_fetch_row ( $result ) ) {
echo '<tr ><td > ' ;
echo implode ( '& nbsp ; </ td >< td > ' , $row ) ;
echo '& nbsp ; </ td > </ tr > ' ;
<
<
}
echo ' </ table >< br /> ' ;
$rowsCount = pg_num_rows ( $result ) ;
echo " Nombre d ' enregistrements : <b >"
?>
</
Ecrivez le programme
principal
.
$rowsCount
.
" </b >" ;
body ></html >
Il vous reste à écrire le programme principal consult.php qui va appeler les trois
codes réalisés ci-dessus.
php
require
require
require
<?
' connectDB . php ' ) ;
' tableDAO . php ' ) ;
( ' printData . php ' ) ;
(
(
?>
Améliorez la généricité
du programme
Chargez la page http://localhost/ird/ihm/consult.php dans le navigateur Firefox et vériez que les données de la table Peche sont achées.
La structure du code développé présente le gros avantage d'être générique : si vous
souhaitez acher les données d'une autre table, il sut de changer le nom de la
table dans la requête SQL. Plutôt que d'avoir à éditer le code tableDAO.php à
chaque fois que vous souhaitez acher une table, vous allez modier le programme
consult.php pour qu'il récupère le nom de la table grâce à la valeur transmise par
$_GET['tableName']. On vériera les valeurs possibles de cette variable grâce à une
liste des tables autorisées (campagne, peche, individu, taxonomie, prelevements).
Modiez également le programme tableDAO.php pour utiliser cette variable comme
nom de table dans la requête SQL .
consult.php
php
$allowedTables
<?
array ( ' campagne ' , ' peche ' , ' individu ' , ' taxonomie ' ,
' prelevements ' ) ;
if ( ! isset ( $_GET [ ' tableName ' ] ) | |
!
in_array ( $_GET [ ' tableName ' ] , $allowedTables ) ) {
$_GET [ ' tableName ' ] = campagne ;
}
require
require
require
=
' connectDB . php ' ) ;
' tableDAO . php ' ) ;
( ' printData . php ' ) ;
(
(
?>
tableDAO.php
$requete
=
" SELECT * FROM "
.
$_GET [ ' tableName ' ] ;
Chargez la page http://localhost/ird/ihm/consult.php?tableName=individu
dans le navigateur Firefox et vériez que les données de la table Individu sont bien
achées.
3
3 Création d'une interface de requête multi-table
L'objectif de cette partie sera de réaliser un formulaire pour rechercher des informations sur les individus
contenus dans la base de données. Les critères de sélections seront proposés grâce à trois listes déroulantes qui
portent respectivement sur le type du prélèvement, la localisation de la pêche et l'espèce concernée. Les résultats
seront achés dans une page HTML.
Démarche
Remplissez les listes
déroulantes
Manipulation
Vous allez commencer par créer un programme PHP chargé de remplir les
listes déroulantes qui vont être utilisées dans le formulaire de recherche.
Créez un chier fillLists.php et écrivez y trois fonctions chargée de remplir chacune des listes : llPrelevementList, llLocalisationList et llEspeceList. La première liste sera remplie directement en fournissant directement
dans le code les valeurs possibles (voir dans le dictionnaire des données la liste
type_prélèvement). La deuxième sera remplie grâce à une requête sur le champ
localisation de la table Peche, en prenant soin de supprimer les doublons. La
troisième liste sera remplie à partir des champs ID_espece et nom_espece_latin
de la table taxonomie. La deuxième et la troisième fonction prendront comme
paramètre la variable $dbconn qui contient la connexion à la base.
function fillPrelevementList ( ) {
return array ( 'MB ' => ' muscle blanc ' , 'FO ' => ' foie ' ,
'SG ' => ' sang ' , 'PE ' => ' paroi estomac ' ,
'PR ' => ' proie ' , 'AN ' => ' anatife ' ) ;
}
function fillLocalisationList ( $dbconn ) {
$localisationList = array ( ) ;
$requete = " SELECT DISTINCT localisation FROM peche " ;
$result = pg_query ( $dbconn , $requete ) ;
if ( ! $result ) {
echo ' Erreur de requete ' ;
exit ;
}
while ( $row = pg_fetch_row ( $result ) ) {
$localisation = $row [ 0 ] ;
$cle_localisation = $row [ 0 ] ;
if ( trim ( $localisation ) == '' ) {
$localisation = ' -- Inconnue - - ' ;
$cle_localisation = ' NULL ' ;
}
$localisationList [ $cle_localisation ]
=
$localisation ;
}
return $localisationList ;
}
function fillEspeceList ( $dbconn ) {
$especeList = array ( ) ;
$requete = " SELECT ID_espece , nom_espece_latin FROM taxonomie " ;
$result = pg_query ( $dbconn , $requete ) ;
if ( ! $result ) {
echo ' Erreur de requete ' ;
exit ;
}
while ( $row = pg_fetch_row ( $result ) ) {
$ID_espece = $row [ 0 ] ;
$nom_espece_latin = $row [ 1 ] ;
$especeList [ $ID_espece ] = $nom_espece_latin ;
}
return $especeList ;
}
4
Créez un formulaire de
recherche avec
HTML_Quickform
Vous pouvez maintenant utiliser la classe PHP HTML_QuickForm pour créer
un formulaire qui contient les trois listes déroulantes ci-dessus. Nommez le
chier individu.php et incluez le chier HTML/QuickForm.php. Créez un formulaire avec les 3 listes déroulantes et un bouton d'envoi. Pour le traitement
du formulaire, contentez vous d'appeler (avec l'instruction include) un programme searchIndividu.php et le programme printData.php qui achera
les données. Voici une solution possible :
php
require ' connectDB . php ' ;
require ' fillLists . php ' ;
require ' HTML / QuickForm . php ' ;
<?
$listPrelevement = fillPrelevementList ( ) ;
$listLocalisation = fillLocalisationList ( $dbconn ) ;
$listEspece = fillEspeceList ( $dbconn ) ;
$form
=
new HTML_QuickForm ( ' formSearchIndividu ' , ' post ' ) ;
$form −>addElement ( ' header ' , null , " Recherche d ' individus " ) ;
$form −>addElement ( ' select ' , ' prelevement ' , ' Type de prelevement ' ,
$listPrelevement ) ;
$form −>addElement ( ' select ' , ' localisation ' , ' Localisation de la peche ' ,
$listLocalisation ) ;
$form −>addElement ( ' select ' , ' espece ' , ' Espece ' ,
$listEspece ) ;
$form −>addElement ( ' submit ' , null , ' Rechercher ' ) ;
$form −>applyFilter ( ' __ALL__ ' , ' trim ' ) ;
$form −>applyFilter ( ' __ALL__ ' , ' pg_escape_string ' ) ;
if
(
$form −>validate ( ) ) { / / i c i on
include ' searchIndividu . php ' ;
include ' printData . php ' ;
lancera
le
traitement
}
else
{
$form −>display ( ) ;
//
}
?>
5
affichage
du
formulaire
Exécutez la requête
avec les critères issus
du formulaire
Il vous faut maintenant créer le programme searchIndividu.php pour utiliser
les valeurs du formulaire et exécuter une requête dans la base. La requête
doit retourner les données suivantes : depuis la table taxonomie le champ
nom_espece_latin, depuis la table individu les champs taille_lf_individu,
poids_individu, sexe_individu, heure_capture, depuis la table peche le champ
date_peche et depuis la table prelevements les champs c, n, dc, dn et c_n. On
classera les résultats dans l'ordre inverse des dates et heures de capture (du
plus ancien au plus récent). Les données n'ont pas besoin d'être achées dans
ce programme (elles le sont déjà grâce à l'appel de printData.php).
php
$requete = "
SELECT nom_espece_latin , taille_LF_individu , poids_individu ,
sexe_individu , heure_capture , date_peche , c , n , dc , dn , c_n
FROM peche AS pec , individu AS ind , taxonomie AS tax , prelevements AS pre
WHERE ind . ID_peche = pec . ID_peche
AND ind . ID_espece = tax . ID_espece
AND ind . ID_individu = pre . ID_individu
AND pre . type_prelevement = '" . $_POST [ ' prelevement ' ] .
" ' AND pec . localisation = '" . $_POST [ ' localisation ' ] .
" ' AND tax . ID_espece = " . $_POST [ ' espece ' ] .
" ORDER BY date_peche , heure_capture DESC
";
<?
$result = pg_query ( $dbconn , $requete ) ;
if ( ! $result ) {
echo ' Erreur de requete ' ;
exit ;
}
$num_fields = pg_num_fields ( $result ) ;
for ( $col = 0 ; $col < $num_fields ; $col ++) {
$fieldsName [ ] = pg_field_name ( $result , $col ) ;
}
?>
Avec le navigateur Firefox, testez le fonctionnement de la recherche en saisissant l'URL http://localhost/ird/ihm/individu.php. Essayez plusieurs
critères de recherche diérents.
6
4 Ajout d'une interface sécurisée pour la saisie d'enregistrements
Dans cette dernière partie, vous allez créer une interface pour la saisie d'enregistrements dans la table Peche.
Pour commencer, il va falloir mettre en place un mécanisme d'authentication pour n'autoriser l'accès qu'à
certains utilisateurs autorisés.
Démarche
Création d'une liste
d'utilisateurs dans la
base
Manipulation
Vous allez ajouter dans la base une nouvelle table qui va contenir les utilisateurs
autorisés à saisir des informations. Exécutez le code SQL suivant dans la base
de données :
∗
∗
∗ Table : u t i l i s a t e u r
∗/
/ ∗==============================================================∗ /
/ ============================================================== /
/
create table utilisateur (
ID
SERIAL
not null ,
login
VARCHAR ( 1 0 )
not null ,
password
VARCHAR ( 3 2 )
not null ,
userlevel
INT4
not null ,
constraint PK_UTILISATEUR primary key ( ID )
);
INSERT INTO utilisateur ( login , password , userlevel )
VALUES ( ' user0 ' , ' 21291505 ea7d2cc217ee680b1a611f4a '
INSERT INTO utilisateur ( login , password , userlevel )
VALUES ( ' user1 ' , ' dfd88155fc25d8025550db1c425089da '
INSERT INTO utilisateur ( login , password , userlevel )
VALUES ( ' user2 ' , ' 654628 c08e6ab1799c96d2f16719af0a '
Utilisation de la classe
AccessControl pour
sécuriser l'accès à une
page
,0);
,1);
,2);
Copiez le chier AccessControl.class.php dans le répertoire
C:\wamp\www\ird\ihm. Créez un nouveau programme formPeche.php
qui inclut les chiers connectDB.php et AccessControl.class.php. Dans une
variable $acl, créez une nouvelle instance de la classe AccessControl avec les
paramètres $dbconn, 'utilisateur' et 1 (respectivement la connexion à la base,
le nom de la table des utilisateurs et le niveau maximum autorisé pour l'accès
à la page). Lancez la méthode run() de l'objet $acl et faites achez un simple
message de test en-dessous.
php
require ' connectDB . php ' ;
require ' AccessControl . class . php ' ;
<?
$acl = & new AccessControl ( $dbconn , ' utilisateur '
$acl −> run ( ) ;
,1);
echo 'La connexion marche ' ;
?>
Avec
le
navigateur
Firefox,
saisissez
l'URL
suivante
:
http://localhost/ird/ihm/formPeche.php. Essayez de vous connecter
avec le login user2, mot de passe tititi. Essayez avec le login user1, mot de
passe tatata. Essayez avec le login user0, mot de passe tototo. Editez le code
de formPeche.php et mettez la valeur 0 pour le 3ème paramètre de la classe
AccessControl. Recommencez les 3 tests de connexion. Conclusion ?
7
Création du formulaire
de saisie pour la table
Peche
Supprimez le message de test dans le code précédent et utilisez la classe
HTML_QuickForm pour créer un formulaire de saisie des valeurs de la
table Peche. Il contiendra plusieurs zone de saisie texte libre pour les
champs : date_peche, saison, association, position_peche, latitude_peche, longitude_peche. Il contiendra également deux listes déroulantes pour sélectionner la campagne et l'association. Pour le contenu de ces listes, vous incluerez
le programme fillLists.php dans lequel vous ajouterez deux fonctions llCampagneList et llAssociationList (pour le contenu de cette dernière voir
le dictionnaire des données). Le champ saison sera déni comme obligatoire
dans le formulaire. Vous utiliserez le type d'élément de formulaire date pour
le champ date_peche. Dans le cas où le formulaire est validé, vous incluerez le
chier insertPeche.php qui insèrera les valeurs saisies.
fillLists.php
function fillCampagneList ( $dbconn ) {
$campagneList = array ( ) ;
$requete = " SELECT ID_campagne FROM campagne " ;
$result = pg_query ( $dbconn , $requete ) ;
if ( ! $result ) {
echo ' Erreur de requete ' ; exit ;
}
while ( $row = pg_fetch_row ( $result ) )
$campagneList [ $row [ 0 ] ] = $row [ 0 ] ;
{
}
return $campagneList ;
}
function fillAssociationList ( ) {
return array ( 'R ' => ' Radeau ' , 'L ' => ' Libre ' ,
'P ' => ' Palangre ' , 'T ' => ' Traine ' ,
'C ' => ' Chalut ' ) ;
}
8
formPeche.php
php
require
require
require
require
<?
' connectDB . php ' ;
' AccessControl . class . php ' ;
' HTML / QuickForm . php ' ;
' fillLists . php ' ;
$acl = & new AccessControl ( $dbconn , ' utilisateur '
$acl −> run ( ) ;
,1);
$listCampagne = fillCampagneList ( $dbconn ) ;
$listAssoc = fillAssociationList ( ) ;
$form = new HTML_QuickForm ( ' formInsertPeche ' , ' post ' ) ;
$form −>addElement ( ' header ' , null , " Saisie d ' une peche " ) ;
$form −>addElement ( ' select ' , ' campagne ' , ' Campagne ' , $listCampagne ) ;
$form −>addElement ( ' text ' , ' ref_peche_campagne ' , ' Ref peche / campagne ' ,
array ( ' size ' =>20, ' maxlength ' = > 3 0 ) ) ;
$options = array ( ' language ' => 'fr ' , ' format '
=> ' dMY ' ,
' minYear '
=> 2 0 0 0 , ' maxYear '
=> 2 0 1 0 ) ;
$form −>addElement ( ' date ' , ' date_peche ' , ' Date de la peche ' , $options ) ;
$form −>addElement ( ' text ' , ' saison ' , ' Saison ' ,
array ( ' size ' =>5, ' maxlength ' = > 2 ) ) ;
$form −>addElement ( ' select ' , ' association ' , ' Association ' , $listAssoc ) ;
$form −>addElement ( ' text ' , ' localisation ' , ' Localisation de la peche ' ,
array ( ' size ' =>20, ' maxlength ' = > 3 0 ) ) ;
$form −>addElement ( ' text ' , ' latitude ' , ' Latitude ' ,
array ( ' size ' =>10, ' maxlength ' = > 1 0 ) ) ;
$form −>addElement ( ' text ' , ' longitude ' , ' Longitude ' ,
array ( ' size ' =>10, ' maxlength ' = > 1 0 ) ) ;
$form −>addElement ( ' submit ' , ' btnSubmit ' , ' Envoyer ' ) ;
$form −>applyFilter ( ' __ALL__ ' , ' trim ' ) ;
$form −>applyFilter ( ' __ALL__ ' , ' pg_escape_string ' ) ;
$form −>addRule ( ' saison ' , ' Vous devez saisir une saison ' ,
' required ' , '' , ' client ' ) ;
$form −>addRule ( ' latitude ' , 'La latitude est une valeur numerique ' ,
' numeric ' , '' , ' client ' ) ;
$form −>addRule ( ' longitude ' , 'La longitude est une valeur numerique ' ,
' numeric ' , '' , ' client ' ) ;
$form −>setRequiredNote ( '* = champs obligatoires ' ) ;
$form −>setJsWarnings ( ' Erreur de saisie ' , ' Veuillez corriger ' ) ;
if
}
$form −>validate ( ) ) { / / i c i on l a n c e r a l ' i n s e r t i o n
include ' insertPeche . php ' ;
else {
$form −>display ( ) ; / / a f f i c h a g e du f o r m u l a i r e
(
}
?>
9
Exécutez la requête
SQL d'insertion dans la
base
Créez le programme insertPeche.php pour insérer dans la base les valeurs
envoyées depuis le formulaire précédent. Vous traiterez le champ date_peche
pour insérer la date au format YYYY-MM-DD. Dans le cas où les valeurs
de latitude et longitude n'ont pas été saisies, vous insèrerez NULL dans les
colonnes correspondantes de la base.
php
$date = $_POST [ ' date_peche ' ] [ 'Y ' ]
$_POST [ ' date_peche ' ] [ 'M ' ] . '-' .
$_POST [ ' date_peche ' ] [ 'd ' ] ;
if ( $_POST [ ' latitude ' ] == '' ) {
$_POST [ ' latitude ' ] = ' NULL ' ;
<?
}
if
.
'-'
.
( $_POST [ ' longitude ' ] == '' ) {
$_POST [ ' longitude ' ] = ' NULL ' ;
}
$requete = "
INSERT INTO peche VALUES (
DEFAULT ,'" . $_POST [ ' campagne ' ] . " '," .
$_POST [ ' ref_peche_campagne ' ] .
" ,'" . $date . " ','" . $_POST [ ' saison ' ] .
" ','" . $_POST [ ' association ' ] . " ','" . $_POST [ ' localisation ' ]
" ',''," . $_POST [ ' latitude ' ] . " ," . $_POST [ ' longitude ' ] . ")" ;
$result = pg_query ( $dbconn , $requete ) ;
if ( ! $result ) {
echo '<b > Erreur de requete </b >< br /> ' ;
exit ;
} else {
echo '<b > Enregistrement ajoute </ b >< br /> ' ;
.
}
echo '<a href =" ' . $_SERVER [ ' PHP_SELF ' ] .
'" > Ajouter un autre enregistrement </ a >< br /> ' ;
?>
Avec le navigateur Firefox, testez l'ajout de valeurs dans la table Peche en saisissant l'URL suivante : http://localhost/ird/formPeche.php et en remplissant le formulaire. Vériez avec phpPgAdmin que les valeurs saisies ont
bien été ajoutées dans la base.
10
Téléchargement