Cet atelier a pour but de permettre de :
connaître les mécanismes de connexion à une base de données,
d'utiliser diverses propriétés objet (héritage, méthodes de classe).
Exercice : Dans MySQL, créez une base de donnée, puis une table vous permettant de stocker les informations de votre utilisateur. Vous pourrez utiliser phpmyadmin par exemple.
n.b : cette table contiendra une clé primaire de type numérique avec la propriété "auto_increment".
Bien, histoire de changer d'air, je vais utiliser Postgres pour ce TP. Commençons par l'installer :
[root@CentOS_AdminBDD ~]# yum install postgresql.x86_64 postgresql-server.x86_64
Initialisation de la base et démarrage du service :
[root@CentOS_AdminBDD ~]# service postgresql initdb [root@CentOS_AdminBDD ~]# /etc/init.d/postgresql start
Starting postgresql service: [ OK ]
Essayons maintenant de se connecter :
[root@CentOS_AdminBDD ~]# su postgres
bash-4.1$ psql
could not change directory to "/root" psql (8.4.11) Type "help" for help.
postgres=#
Création d'une nouvelle de données et de la table associée :
postgres=# CREATE DATABASE eof OWNER postgres;
CREATE DATABASE
postgres=# \connect eof;
psql (8.4.11) You are now connected to database "eof".
eof=# CREATE TABLE users (id_user serial PRIMARY KEY, nom varchar(25) NOT NULL, prenom varchar(25) NOT NULL, login varchar(25) NOT NULL, password varchar(25) NOT NULL, informations text, cv_path varchar(75));
NOTICE: CREATE TABLE will create implicit sequence "users_id_user_seq" for serial column "users.id_user" NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "users_pkey" for table "users" CREATE TABLE
eof=# \d
List of relations Schema | Name | Type | Owner --------+-------------------+----------+---------- public | users | table | postgres public | users_id_user_seq | sequence | postgres (2 rows)
eof=# \d+ users;
Table "public.users" Column | Type | Modifiers | Storage | Description --------------+-----------------------+---------------------------------------------------------+----------+------------- id_user | integer | not null default nextval('users_id_user_seq'::regclass) | plain | nom | character varying(25) | not null | extended | prenom | character varying(25) | not null | extended | login | character varying(25) | not null | extended | password | character varying(25) | not null | extended | informations | text | | extended | cv_path | character varying(75) | | extended | Indexes: "users_pkey" PRIMARY KEY, btree (id_user) Has OIDs: no
Ajout d'un utilisateur :
[root@CentOS_AdminBDD ~]# createuser cvanvincq
Shall the new role be a superuser? (y/n) n Shall the new role be allowed to create databases? (y/n) n Shall the new role be allowed to create more new roles? (y/n) n
[root@CentOS_AdminBDD ~]# su postgres
bash-4.1$ psql
postgres=# GRANT ALL PRIVILEGES ON DATABASE eof TO cvanvincq; postgres=# \q
bash-4.1$ exit
bash-4.1$ exit
Un dernier test pour la route :
[root@CentOS_AdminBDD ~]# su - cvanvincq
[cvanvincq@CentOS_AdminBDD ~]$ psql -d eof
psql (8.4.11) Type "help" for help.
eof=> \du
List of roles Role name | Attributes | Member of -----------+-------------+----------- cvanvincq | | {} postgres | Superuser | {} : Create role : Create DB
eof=> \l
List of databases Name | Owner | Encoding | Collation | Ctype | Access privileges -----------+----------+----------+-------------+-------------+------------------------ eof | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =Tc/postgres : postgres=CTc/postgres : cvanvincq=CTc/postgres postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres : postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres : postgres=CTc/postgres (4 rows)
Pour créer une connexion Postgres sous PHP, on utilise les fonctions pg_connect ou pg_pconnect.
<?php $dbconnect = pg_connect("host='localhost' dbname='eof' user='cvanvincq'"); ?>
n.b : pour ceux qui se feraient avoir comme moi, n'oubliez pas de désactiver (ou adapter) le module SELINUX si vous avez une machine du type Redhat-like !.
Pour effectuer une requête, on utilise pg_query.
<?php $dbconnect = pg_connect("host='localhost' dbname='eof' user='cvanvincq'"); $result = pg_query($dbconnect, "SELECT nom, prenom FROM users"); ?>
Pour récupérer un résultat, on peut utiliser pg_fetch_row ou autres équivalents (pg_fetch_array, pg_fetch_object, etc.) :
<?php $dbconnect = pg_connect("host='localhost' dbname='eof' user='cvanvincq'"); $result = pg_query($dbconnect, "SELECT nom, prenom FROM users"); while ($row = pg_fetch_row($result)) { echo "Nom : ".$row[0]."\n"; echo "Prémom : ".$row[1]."\n"; } ?>
Avant de tester quelques reqûetes, il peut être opportun d'alimenter la base préalablement.
eof=> INSERT INTO users (nom, prenom, login, password) VALUES ('Pierre', 'Dupont', 'pdupont', '01011954');
INSERT 0 1
eof=> select * from users;
id_user | nom | prenom | login | password | informations | cv_path ---------+--------+--------+---------+----------+--------------+--------- 1 | Pierre | Dupont | pdupont | 01011954 | | (1 row)
En reprenant notre exemple précédent :
[root@CentOS_AdminBDD html]# cat index.php
<?php $dbconnect = pg_connect("host='localhost' dbname='eof' user='cvanvincq'"); $result = pg_query($dbconnect, "SELECT nom, prenom FROM users"); while ($row = pg_fetch_row($result)) { echo "Nom : ".$row[0]."\n"; echo "Prémom : ".$row[1]."\n"; } ?>
[root@CentOS_AdminBDD html]# php index.php
Nom : Pierre Prémom : Dupont
Créez une classe fille (qui hérite) de la classe User, et ajoutez lui une propriété id, et une méthode doInsert permettant d'insérer les données de votre objet dans la base de données.
Cette méthode ne gérera pas la connexion à la base, mais juste la requête d'insertion.
Transformez maintenant votre page affichage.php en page d'enregistrement en changeant le type d'objet utilisé (classe UserDb à la place de User) et ajoutez un appel à la méthode doInsert.
Testez là avec un jeu d'enregistrement simple.
Nouvelle version du fichier ObjectUser.php :
<?php class User { public function __construct() {} public function getName() { return $this->mName; } public function getSurname() { return $this->mSurname; } public function getLogin() { return $this->mLogin; } public function getPassword() { return $this->mPassword; } public function getAnotherInformations() { return $this->mAnotherInformations; } public function getCv() { return $this->mCv; } public function setName($mName) { $this->mName = $mName; } public function setSurname($mSurname) { $this->mSurname = $mSurname; } public function setLogin($mLogin) { $this->mLogin = $mLogin; } public function setPassword($mPassword) { $this->mPassword = $mPassword; } public function setAnotherInformations($mAnotherInformations) { $this->mAnotherInformations = $mAnotherInformations; } public function setCv($mCv) { $this->mCv = $mCv; } public static function printForm() { $output = "<form name=\"form\" enctype=\"multipart/form-data\" method=\"POST\" action=\"". $_SERVER['PHP_SELF'] ."\">\n"; $output .= "<table>\n"; $output .= "<tr>\n"; $output .= "<td>Nom : </td>\n"; $output .= "<td><input type=\"text\" name=\"surname\" /></td>\n"; $output .= "</tr>\n"; $output .= "<tr>\n"; $output .= "<td>Prénom : </td>\n"; $output .= "<td><input type=\"text\" name=\"name\" /></td>\n"; $output .= "</tr>\n"; $output .= "<tr>\n"; $output .= "<td>Identifiant : </td>\n"; $output .= "<td><input type=\"text\" name=\"login\" /></td>\n"; $output .= "</tr>\n"; $output .= "<tr>\n"; $output .= "<td>Mot de passe : </td>\n"; $output .= "<td><input type=\"password\" name=\"password\" /></td>\n"; $output .= "</tr>\n"; $output .= "<tr>\n"; $output .= "<td>Informations complémentaires : </td>\n"; $output .= "<td><textarea name=\"anotherInformations\" rows=\"5\" cols=\"30\"></textarea></td>\n"; $output .= "</tr>\n"; $output .= "<tr>\n"; $output .= "<input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"30000\" />\n"; $output .= "<td>Curriculum Vitae : </td>\n"; $output .= "<td><input type=\"file\" name=\"cv\" /></td>\n"; $output .= "</tr>\n"; $output .= "<tr>\n"; $output .= "<td colspan=\"2\"><input type=\"submit\" value=\"Valider\" /></td>"; $output .= "</tr>\n"; $output .= "</table>\n"; $output .= "</form>\n"; echo $output; } public function execForm() { if (!empty($_POST['name'])) $this->mName = $_POST['name']; if (!empty($_POST['surname'])) $this->mSurname = $_POST['surname']; if (!empty($_POST['login'])) $this->mLogin = $_POST['login']; if (!empty($_POST['password'])) $this->mPassword = $_POST['password']; if (!empty($_POST['anotherInformations'])) $this->mAnotherInformations = $_POST['anotherInformations']; if (!empty($_FILES['cv'])) { $uploads_dir = '/uploads'; if ($_FILES['cv']['error'] == UPLOAD_ERR_OK) { $tmp_name = $_FILES['cv']['tmp_name']; $name = $_FILES['cv']['name']; move_uploaded_file($tmp_name, ".$uploads_dir/$name"); $this->mCv = $uploads_dir . "/" . $name; } } } public function printData() { echo "Prénom :" . $this->mName . "<br/>\n"; echo "Nom :" . $this->mSurname . "<br/>\n"; echo "Identifiant :" . $this->mLogin . "<br/>\n"; echo "Mot de passe :" . $this->mPassword . "<br/>\n"; echo "Informations complémentaires :" . $this->mAnotherInformations . "<br/>\n"; echo "Fichier uploadé : <a href=\"".$this->mCv."\">lien</a>."; } private $mName; private $mSurname; private $mLogin; private $mPassword; private $mAnotherInformations; private $mCv; } class UserDb extends User { public function __construct() { parent::__construct(); } public function getId() { return $this->mId; } public function setId($mId) { $this->mId = $mId; } public function connect($host = "localhost", $dbname = "eof", $user = "cvanvincq") { if ($this->mConnection = pg_connect("host='".$host."' dbname='".$dbname."' user='".$user."'")) return true; else return false; } public function disconnect() { if (pg_close($this->mConnection)) return true; else return false; } public function doInsert() { pg_query(" INSERT INTO users(nom, prenom, login, password, informations, cv_path) VALUES( '".$this->getSurname()."', '".$this->getName()."', '".$this->getLogin()."', '".$this->getPassword()."', '".$this->getAnotherInformations()."', '".$this->getCv()."' ) "); } private $mConnection; private $mId; } ?>
Le fichier Formulaire.php :
<?php include_once("./ObjectUser.php"); echo "<html>"; echo "<head><title>Formulaire.php</title></head>"; echo "<body>"; if (empty($_POST) && empty($_FILES)) { UserDb::printForm(); } else { $monUtilisateur = new UserDb(); $monUtilisateur->execForm(); $monUtilisateur->printData(); $monUtilisateur->connect(); $monUtilisateur->doInsert(); $monUtilisateur->disconnect(); } echo "</body>"; echo "</html>"; ?>
Dans un premier temps, ajoutez une méthode de classe à UserDb permettant récupérer une liste d'objets UserDb à partir de la base de données.
Créez une page d'affichage de cette liste (vous utiliserez une boucle foreach et appellerez sur chaque objet, la méthode printData).
Le code de la méthode récupérant la liste des utilisateurs
<?php // [...] public function &getUserDbList() { if (!($result = pg_query("SELECT id_user, nom, prenom, login, password, informations, cv_path FROM users;"))) die("getUserBdList error"); $cpt = 0; while ($row = pg_fetch_assoc($result)) { $userTmp = new User(); $userTmp->setName($row['prenom']); $userTmp->setSurname($row['nom']); $userTmp->setLogin($row['login']); $userTmp->setPassword($row['password']); $userTmp->setAnotherInformations($row['informations']); $userTmp->setCv($row['cv_path']); $userDbList[$cpt++] = $userTmp; } return $userDbList; } // [...] ?>
Le code de la page ListeUtilisateur.php :
<?php include_once("./ObjectUser.php"); /* Récupération de la liste des utilisateurs */ $userDbInstance = new UserDb(); $userDbInstance->connect(); $userDbList =& $userDbInstance->getUserDbList(); $userDbInstance->disconnect(); echo "<html>"; echo "<head><title>ListeUtilisateur.php</title></head>"; echo "<body>"; foreach($userDbList as $monUtilisateur) { $monUtilisateur->printData(); echo "<hr />"; } echo "</body>"; echo "</html>"; ?>
Voici une illustration du rendu :
Les sources du TP sont disponibles ici-même.