3. La classe Database

La base de données

Comme indiqué dans le titre, nous allons commencer par travailler avec notre base de données.

Voici le schéma SQL actuel de notre base de données blog :

CREATE DATABASE IF NOT EXISTS `blog` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

Tous les scripts sont dans le dossier sql à la racine du projet

Créez donc ce dossier sql à la racine de votre projet et créez le fichier db.sql  à l'intérieur avec le contenu de la requête sql ci-dessus.

 

La classe Database

Passons maintenant côté PHP où nous allons créer une classe concernant notre base de données dans un fichier appelé  Database.php  (à la racine de notre projet):

<?php

class Database
{
    
}

Attention au nommage de la classe : la première lettre de la classe commence par une Majuscule !

La première chose dont nous devons nous occuper, c'est de se connecter à notre base. Pour ceci, nous allons créer une méthode (fonction dépendante d'un objet) que nous allons appeler  getConnection()

<?php

class Database
{
    public function getConnection()
    {
        
    }
}
Euh oui, mais ta méthode, elle ne fait rien là ?

Tout juste, nous allons ajouter le code à l'intérieur, vous vous rappelez du try/catch ? Ajoutons-le 😁

<?php

class Database
{
    //Méthode de connexion à notre base de données
    public function getConnection()
    {
        //Tentative de connexion à la base de données
        try{
            $connection = new PDO('mysql:host=localhost;dbname=blog;charset=utf8', 'root', 'root');
            $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }
        //On lève une erreur si la connexion échoue
        catch(Exception $errorConnection)
        {
            die ('Erreur de connection :'.$errorConnection->getMessage());
        }
    }
}

Pensez à changer les valeurs de host, dbname, user (ici root), et pass (ici root aussi) pour que cela fonctionne avec votre application web

Créons maintenant un fichier  home.php  (à la racine de notre projet) avec le contenu suivant :

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="utf-8">
    <title>Mon blog</title>
</head>

<body>
    <div>
        <h1>Mon blog</h1>
        <p>En construction</p>
    </div>
</body>
</html>

Si vous essayez d'accéder à la page web, ici http://localhost/blog/home.php, vous devriez avoir l'affichage correct.

Pourquoi je n'ai rien qui ne s'affiche à l'écran concernant la connexion à la base de données ? Ça ne marche pas ton truc ? 😒

Euh... on se calme ! Pour le moment, nous avons juste créé une méthode pour nous connecter à la base de données, nous ne l'avons jamais utilisé dans notre application. Modifions maintenant notre fichier  home.php  dans lequel nous allons faire appel à cette méthode :

<?php
//On inclut le fichier dont on a besoin (ici à la racine de notre site)
require 'Database.php';
?>
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="utf-8">
    <title>Mon blog</title>
</head>

<body>
<div>
    <h1>Mon blog</h1>
    <p>En construction</p>
    <?php
    //On crée un nouvel objet $db, qui est une instance de la classe Database
    $db = new Database();
    //On fait appel à notre méthode getConnection()
    $db->getConnection();
    ?>
</div>
</body>
</html>
C'est tout ? Ça ne marche toujours pas ! Rien ne s'affiche ! Je saute sur mon ordinateur à pieds joints ?

Ça ne le fera pas mieux marcher 😝

Pour le moment, rien ne s'affiche, mais c'est tout à fait normal. Nous ne lui avons pas demandé d'afficher quoi que ce soit à l'écran. Modifions légèrement notre code pour vérifier ce qui se passe à l'écran :

Le fichier Database.php :

<?php

class Database
{
    //Méthode de connexion à notre base de données
    public function getConnection()
    {
        //Tentative de connexion à la base de données
        try{
            $connection = new PDO('mysql:host=localhost;dbname=blog;charset=utf8', 'root', 'root');
            $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            //On renvoie un message avec le mot-clé return
            return 'Connexion OK';
        }
        //On lève une erreur si la connexion échoue
        catch(Exception $errorConnection)
        {
            die ('Erreur de connection :'.$errorConnection->getMessage());
        }

    }
}

Le fichier home.php :

<?php
//On inclut le fichier dont on a besoin (ici à la racine de notre site)
require 'Database.php';
?>
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="utf-8">
    <title>Mon blog</title>
</head>

<body>
    <div>
        <h1>Mon blog</h1>
        <p>En construction</p>
        <?php

        $db = new Database();
        //On ajoute un echo pour vérifier qu'un message s'affiche à l'écran
        echo $db->getConnection();
        ?>
    </div>
</body>
</html>

Ici, on a appliqué deux modifications :

- dans notre classe Database, on renvoie un message avec le mot-clé return ;

- dans notre fichier home.php, ce message est affiché grâce au echo ajouté.

Si vous actualisez la fenêtre de votre navigateur, en retournant sur http://localhost/blog/home.php, tout fonctionne.

Si vous essayez de changer un paramètre de connexion (hôte, user ou pass), le navigateur web devrait vous afficher une erreur (le message contenu dans le catch écrit précédemment).

 Youpi, ça marche !!! On fait quoi maintenant ? Quelle est l'étape suivante ?

Notre connexion fonctionne pour le moment, mais ce n'est pas encore idéal.

Nous allons y remédier dès maintenant.

 

Améliorons notre classe Database

Notre classe fonctionne maintenant, pourtant nous ne nous connecterons pas à celle-ci de la sorte.

Ici, la connexion se fait, mais aucune interaction n'est faite dans celle-ci.

Oui mais c'est ce qu'on va faire par la suite ? 

Vous avez raison. Mais rien n'empêche d'améliorer notre application régulièrement. Nous allons régulièrement réécrire notre code pour améliorer notre application : on appelle ça la refactorisation.

Nous faisons actuellement face à un problème : les paramètres de connexion sont noyés dans le code.

On va y remédier immédiatement 😉

 

Modification de notre fichier Database

Nous allons sortir les paramètres de connexion et les stocker dans des ... CONSTANTES

Pourquoi pas dans des variables ?

Les paramètres de connexion ne vont pas changer, les constantes sont donc parfaitement adaptées à notre besoin.

Voici donc notre classe mise à jour :

<?php

class Database
{
    //Nos constantes
    const DB_HOST = 'mysql:host=localhost;dbname=blog;charset=utf8';
    const DB_USER = 'root';
    const DB_PASS = 'root';

    //Méthode de connexion à notre base de données
    public function getConnection()
    {
        //Tentative de connexion à la base de données
        try{
            $connection = new PDO(self::DB_HOST, self::DB_USER, self::DB_PASS);
            $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            //On renvoie un message avec le mot-clé return
            return 'Connexion OK';
        }
        //On lève une erreur si la connexion échoue
        catch(Exception $errorConnection)
        {
            die ('Erreur de connection :'.$errorConnection->getMessage());
        }

    }
}
self ? self ? Pourquoi self et pas $this ?

self fait référence à la classe et $this à l'objet, ici les paramètres ne vont pas changer, ils appartiennent à la classe : on utilise donc self.

On peut de la même façon remplacer self par le nom de la classe, ici Database

 

<?php

class Database
{
    //Nos constantes
    const DB_HOST = 'mysql:host=localhost;dbname=blog;charset=utf8';
    const DB_USER = 'root';
    const DB_PASS = 'root';

    //Méthode de connexion à notre base de données
    public function getConnection()
    {
        //Tentative de connexion à la base de données
        try{
            $connection = new PDO(Database::DB_HOST, Database::DB_USER, Database::DB_PASS);
            $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            //On renvoie un message avec le mot-clé return
            return 'Connexion OK';
        }
        //On lève une erreur si la connexion échoue
        catch(Exception $errorConnection)
        {
            die ('Erreur de connection :'.$errorConnection->getMessage());
        }

    }
}

Par la suite, je garderai self et non Database, pour une raison simple : si le nom de la classe doit changer, il n'y aura pas de modification supplémentaire à faire que de changer le nom de la classe.

 

Versionning

Nous allons versionner notre code avec git, vous pourrez ainsi l'héberger sur une plateforme de votre choix (GitHub, Gitlab, Bitbucket...).

Pour ce projet, j'ai choisi l'hébergement avec Github, mais vous êtes bien évidemment libres de votre choix 😉

 

Pour ceux qui utilisent PHPStorm

Créons maintenant un fichier .gitignore à la racine de notre projet et ajoutons le contenu suivant :

.idea/ 

Cela permettra de ne pas versionner le dossier idea qui est utilisé par PHPStorm pour configurer votre projet.

 

Quelques révisions

Si vous avez besoin de revoir certains points, voici les liens en conséquence :

Documentation MySQL
classe en PHP
PDO
require
constantes
git

 

Bilan

Dans ce chapitre, nous avons travaillé avec notre classe  Database  qui permettra d'interagir avec notre base de données.

Vous pouvez retrouver le code associé à ce chapitre sur GitHub.