Tutoriel de correction du TP5 

Partie 1 - Utilisation d'un DAO s'appuyant sur une base de données MySQL

Mise en place

(On suppose qu'un répertoire tpdsi a été créé à la racine du site  web et que la table TICKET a été créée dans la base MySQL, par exemple en suivant ce tutoriel utilisant phpMyAdmin.) 

Créer un répertoire tp5 sous le répertoire tpdsi ; y dézipper l'archive correction du TP4 .
Si le serveur web est lancé sur la machine locale,  on doit pouvoir visualiser le formulaire de saisie de ticket en tapant l'URL http://localhost/tpdsi/tp5/editTicket.php dans un navigateur.

(Lancer Eclipse.) Dans Eclipse, sélectionner le projet tpdsi précédemment créé et utiliser la touche F5 (File->Refresh)
Le répertoire tp5 apparaît alors  ainsi que tous les fichiers qu'il contient.

Définition de la classe FileTicketDAO

Sélectionner le fichier TicketDAO.class.php  

Edit->Copy
Edit->Paste

Saisir FileTicketDAO.class.php pour nom de fichier. Valider.

Renommer la classe et le constructeur FileTicketDAO.

Définition de l'interface TicketDAO

Éditer le fichier TicketDAO.class.php.
Supprimer  variables d'instance, constructeur et méthodes spécifiques pour ne garder que le code suivant.

<?php
include_once 'Ticket.class.php';

abstract class TicketDAO {
    /**
     * retourne la  collection (un tableau simple) de tous les tickets
     * (le tableau retourné peut être vide.)
     */
    abstract function findAll();

    /**
     * retourne l'instance de Ticket d'ID $searchedTicketId
     * (ou null si le ticket n'est pas trouvé)
     */
    abstract function findById($searchedTicketId);

    abstract function save($ticket);

}
?>

Définition de la classe MySQLiTicketDAO

Sélectionner le fichier TicketDAO.class.php  

Edit->Copy
Edit->Paste

Saisir MySQLiTicketDAO.class.php pour nom de fichier. Valider.

Renommer la classe MySQLiTicketDAO.

Définir un fichier de configuration mysql.conf.php pour les paramètres d'accès à la base :

<?php
// global variables
$GLOBALS['g_Host'] = $g_Host = "localhost";  // web server hostname
$GLOBALS['g_User'] = $g_User = "root";       // MySQL admin user name
$GLOBALS['g_Password'] = $g_Password = "";   // MySQL admin password
$GLOBALS['g_DbName'] = $g_DbName = "yahd";   // MySQL database name
?>

Inclure ce fichier dans MySQLiTicketDAO.class.php , déclarer la classe MySQLiTicketDAO et ses attributs et se connecter à la base de données  en appelant  mysqli_connect() dans le constructeur :

<?php
include_once 'Ticket.class.php';
include_once 'TicketDAO.class.php';

class MySQLiTicketDAO extends TicketDAO {
    private $mysqli;
    private $TABLE_NAME = 'TICKET';
    private $COLUMN_NAMES = ' ticketID , applicationName , login , priority , type , creationDate , oneLiner , detailedDescription , attachmentName ';

    function __construct() {
        include 'mysql.conf.php';
        $this->mysqli = @mysqli_connect ($g_Host, $g_User, $g_Password, $g_DbName);
        if ( $this->mysqli == null ) {
            echo "Echec de la connexion: ".mysqli_connect_error()."<br/>";
            exit();
        }
    }

// ...

La méthode  findAll() utilise les méthodes  mysqli::query() et mysqli_result::fetch_array() pour obtenir chaque enregistrement de la table TICKET; pour chacun de ces enregistrements un ticket est instancié et ajouté au tableau résultat :

    function findAll() {
        $result = array ();
        $query = "SELECT $this->COLUMN_NAMES FROM $this->TABLE_NAME";
        $qresult = $this->mysqli->query($query);
        if ( !$qresult ) {
            echo "Error calling findAll() : " . $this->mysqli->error;
            return $result;
        }
        while ( $row = $qresult->fetch_array() ) {
            list ($ticketID, $applicationName, $login, $priority, $type, $creationDate, $oneLiner, $detailedDescription, $attachmentName) = $row;
            $newTicket = new Ticket($applicationName, $login, $priority, $type, $creationDate, $oneLiner, $detailedDescription, $attachmentName, $ticketID);
            $result[] = $newTicket; // ajoute le nouveau ticket au tableau
        }
        return $result;
    }

La méthode insert() crée une requête d'insertion (en utilisant la syntaxe here-doc) puis l'exécute:

    /**
     * insère $ticket comme un nouvel enregistrement
     */
    function insert($ticket) {
        $applicationName = $ticket->getApplicationName();
        $login = $ticket->getLogin();
        $priority = $ticket->getPriority();
        $type = $ticket->getType();
        $creationDate = $ticket->getCreationDate();
        // protéger les caractères guillemets
        $oneLiner = addslashes($ticket->getOneLiner());
        $detailedDescription = $ticket->getDetailedDescription();
        $attachmentName = $ticket->getAttachmentName();
        $insertquery =<<<EOT
        INSERT INTO $this->TABLE_NAME ( applicationName , login , priority , type , creationDate , oneLiner , detailedDescription , attachmentName )
        VALUES ( '$applicationName', '$login', '$priority', '$type', '$creationDate', '$oneLiner', '$detailedDescription', '$attachmentName') ;
EOT;
        $result = $this->mysqli->query($insertquery);
        if ( $this->mysqli->errno != 0 ) echo "Error calling insert() : " . $this->mysqli->error;
    }

Modifications de la classe AppService

Dans AppService.class.php , plutôt que d'instancier un DAO dans chaque méthode, on va définir un attribut que l'on initialise dans le constructeur (et que l'on utilisera dans chaque méthode):

class AppService {
    private $ticketDAO;
    function AppService() {
        $this->ticketDAO = new MySQLiTicketDAO();
    }
    // ...

(Enlever aussi le mot static dans la signature de toutes les méthodes utilisant cet attribut $this->ticketDAO)

Utilisations de AppService

Dans chaque fichier utilisant la classe AppService, après avoir créé une instance :

    $appService = new AppService();

Remplacer tous les appels de la forme

    AppService::f()

par

    $appService->f()

Tester en créant ce ticket de priorité urgente et vérifier la base MySQL.