L3 Info : PHP et Applications Web
 
◃  Ch. 5 PDO : PHP Data Object  ▹
 

Objet Métier

Problématique

Associer dans une classe les besoins d'une application et les contraintes provenant du SI. Dans le cas de la base LMSF, on dispose de 4 tables qui dispersent des informations souvent manipulées ensemble, par exemple, la notice d'un livre. Un objet métier devra permettre de faire la synthèse entre la problématique du SI et de l'application, typiquement :

  • permettre l'accès à une donnée métier (en général à l'aide d'une vue SQL),
  • permettre sa création, son édition et sa sauvegarde (qui dépendent souvent de plusieurs tables).

Configuration des paramètres de connexion à la BD


$_ENV['host'] = "ust-infoserv.univlehavre.lan";
$_ENV['user'] = "xy123456";
$_ENV['db'] = "xy123456";
$_ENV['passwdt'] = "***********";
    

Exemple simple : la classe LivreMetier

class LivreMetier {

    /**
     * gestion statique des accès SGBD
     * @var PDO
     */ 
    private static $_pdo;

    /**
     * gestion statique de la requête préparée de selection
     * @var PDOStatement
     */ 
    private static $_pdos_select;

    /**
     * gestion statique de la requête préparée de mise à jour
     *  @var PDOStatement
     */ 
    private static $_pdos_update;

    /**
     * gestion statique de la requête préparée de d'insertion
     * @var PDOStatement
     */ 
    private static $_pdos_insert;

    /**
     * gestion statique de la requête préparée de suppression
     * @var PDOStatement
     */ 
    private static $_pdos_delete;

    /**
     * PreparedStatement associé à un SELECT, calcule le nombre de livres de la table
     * @var PDOStatement;
        */
    private static $_pdos_count;

    /**
     * PreparedStatement associé à un SELECT, récupère tous les livres
     * @var PDOStatement;
        */
     private static $_pdos_selectAll;



    /**
     * Initialisation de la connexion et mémorisation de l'instance PDO dans LivreMetier::$_pdo
     */ 
    public static function initPDO() {
        self::$_pdo = new PDO("mysql:host=".$_ENV['host'].";dbname=".$_ENV['db'],$_ENV['user'],$_ENV['passwd']);
        // pour récupérer aussi les exceptions provenant de PDOStatement
        self::$_pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }

    /**
     * préparation de la requête SELECT * FROM livre
     * instantiation de self::$_pdos_selectAll
        */
    public static function initPDOS_selectAll() {
        self::$_pdos_selectAll = self::$_pdo->prepare('SELECT * FROM livre');
    }

     /**
     * méthode statique instanciant LivreMetier::$_pdo_select
     */ 
    public static function initPDOS_select() {
        self::$_pdos_select = self::$_pdo->prepare('SELECT * FROM livre WHERE liv_num= :numero');
    }

    /**
     * méthode statique instanciant LivreMetier::$_pdo_update
     */ 
    public static function initPDOS_update() {
        self::$_pdos_update =  self::$_pdo->prepare('UPDATE livre SET liv_titre=:titre, liv_depotlegal=:depotLegal WHERE liv_num=:numero');
    }

    /**
     * méthode statique instanciant LivreMetier::$_pdo_insert
     */ 
    public static function initPDOS_insert() {
        self::$_pdos_insert = self::$_pdo->prepare('INSERT INTO livre VALUES(:numero,:titre,:depotLegal)');
    }

    /**
     * méthode statique instanciant LivreMetier::$_pdo_delete
     */ 
    public static function initPDOS_delete() {
        self::$_pdos_delete = self::$_pdo->prepare('DELETE FROM livre WHERE liv_num=:numero');
    }

    /**
     * préparation de la requête SELECT COUNT(*) FROM livre
     * instantiation de self::$_pdos_count
        */
    public static function initPDOS_count() {
        if (!isset(self::$_pdo))
            self::initPDO();
        self::$_pdos_count = self::$_pdo->prepare('SELECT COUNT(*) FROM livre');
    }


     /**
     * numéro du livre (identifiant dans la table Livre)
     * @var int
     */ 
    protected $liv_num;

    /**
     * titre du livre
     * @var string
     */ 
    protected $liv_titre;

    /**
     * dépot légal du livre
     *   @var string
     */ 
    protected $liv_depotlegal;

    /**
     * attribut interne pour différencier les nouveaux objets des objets créés côté applicatif de ceux issus du SGBD
     * @var bool
     */ 
    private $nouveau = TRUE;

    /**
     * @return $this->liv_num
     */ 
    public function getLiv_num() : int {
        return $this->liv_num;
    }

    /**
     * @param $liv_num
     */ 
    public function setLiv_num($liv_num): void {
        $this->liv_num=$liv_num;
    }

    /**
     * @return $this->liv_titre
     */ 
    public function getLiv_titre() : string {
        return $this->liv_titre;
    }

    /**
     * @param $liv_titre
     */ 
    public function setLiv_titre($liv_titre): void {
        $this->liv_titre=$liv_titre;
    }

    /**
     * @return $this->liv_depotlegal
     */ 
    public function getLiv_depotlegal() : string {
        return $this->liv_depotlegal;
    }

    /**
     * @param $liv_depotlegal
     */ 
    public function setLiv_depotlegal($liv_depotlegal): void {
        $this->liv_depotlegal=$liv_depotlegal;
    }

    /**
     * @return $this->nouveau
     */ 
    public function getNouveau() : bool {
        return $this->nouveau;
    }

    /**
     * @param $nouveau
     */ 
    public function setNouveau($nouveau): void {
        $this->nouveau=$nouveau;
    }

    /**
     * @return un tableau de tous les LivreMetier
     */ 
    public static function getAll(): array {
        try {
            if (!isset(self::$_pdo))
                self::initPDO();
            if (!isset(self::$_pdos_selectAll))
                self::initPDOS_selectAll();
            self::$_pdos_selectAll->execute();
            // résultat du fetch dans une instance de LivreMetier
            $lesLivres = self::$_pdos_selectAll->fetchAll(PDO::FETCH_CLASS,'LivreMetier');
            return $lesLivres;
        }
        catch (PDOException $e) {
            print($e);
        }
    }


    /**
     * initialisation d'un objet métier à partir d'un enregistrement de livre
     * @param $liv_num un identifiant de livre
     * @return l'instance de LivreMetier associée à $liv_num
     */ 
    public static function initLivreMetier($liv_num) : LivreMetier {
        try {
	        if (!isset(self::$_pdo))
	            self::initPDO();
	        if (!isset(self::$_pdos_select))
	            self::initPDOS_select();
	        self::$_pdos_select->bindValue(':numero',$liv_num);
	        self::$_pdos_select->execute();
        // résultat du fetch dans une instance de LivreMetier
	        $lm = self::$_pdos_select->fetchObject('LivreMetier');
	        if (isset($lm) && ! empty($lm))
	            $lm->setNouveau(FALSE);
	        if (empty($lm))
                throw new Exception("Livre $liv_num inexistant dans la table Livre.\n");
	        return $lm;
        }
        catch (PDOException $e) {
	        print($e);
        }
    }

    /**
     * sauvegarde d'un objet métier
     * soit on insère un nouvel objet
     * soit on le met à jour
     */ 
    public function save() : void {
        if (!isset(self::$_pdo))
            self::initPDO();
        if ($this->nouveau) {
            if (!isset(self::$_pdos_insert)) {
	            self::initPDOS_insert();
            }
            self::$_pdos_insert->bindParam(':numero', $this->liv_num);
            self::$_pdos_insert->bindParam(':titre', $this->liv_titre);
            self::$_pdos_insert->bindParam(':depotLegal', $this->liv_depotlegal);
            self::$_pdos_insert->execute();
            $this->setNouveau(FALSE);
        }
        else {
            if (!isset(self::$_pdos_update))
	            self::initPDOS_update();
            self::$_pdos_update->bindParam(':numero', $this->liv_num);
            self::$_pdos_update->bindParam(':titre', $this->liv_titre);
            self::$_pdos_update->bindParam(':depotLegal', $this->liv_depotlegal);
            self::$_pdos_update->execute();
        }
    }

    /**
     * suppression d'un objet métier
     */ 
    public function delete() :void {
        if (!isset(self::$_pdo))
            self::initPDO();
        if (!$this->nouveau) {
            if (!isset(self::$_pdos_delete)) {
	            self::initPDOS_delete();
            }
            self::$_pdos_delete->bindParam(':numero', $this->liv_num);
            self::$_pdos_delete->execute();
        }
        $this->setNouveau(TRUE);
    }

    /**
     * nombre d'objets metier disponible dans la table
     */
    public static function getNbLivres() : int {
        if (!isset(self::$_pdos_count)) {
            self::initPDOS_count();
        }
        self::$_pdos_count->execute();
        $resu = self::$_pdos_count->fetch();
        return $resu[0];
    }



    /**
     * affichage élémentaire
     */ 
    public function __toString() : string {
        $ch = "<table border='1'><tr><th>liv_num</th><th>liv_titre</th><th>liv_depot_legal</th><th>nouveau</th></tr><tr>";
        $ch.= "<td>".$this->liv_num."</td>";
        $ch.= "<td>".$this->liv_titre."</td>";
        $ch.= "<td>".$this->liv_depotlegal."</td>";
        $ch.= "<td>".$this->nouveau."</td>";
        $ch.= "</tr></table>";
        return $ch;
    }
}