### Définir des constantes

définir des constantes

Seuls les types de données scalaires (booléen, entier, double et chaîne de caractères) peuvent être affectés comme valeur d'une constante.

Une fois définie, la valeur d'une constante de classe n'est plus modifiable.

Tous les objets instances de la classe contenant les constantes partagent la valeur de ces constantes. Il y ont tous accès en lecture, mais pas en écriture.

Il n'est pas possible de spécifier la visibilité d'une constante. Les constantes ont une visibilité `public` par défaut.

Pour illustrer l'utilisation des constantes, nous allons ajouter un nouvel attribut à la classe Guitare. L'attribut `son` définira l'acoustique de la guitare, à savoir : acoustique, à résonateur, électro-acoustique, électrique. Ces valeurs seront stockées dans 4 constantes.

Exemple : définition de constantes
<?php ob_start(); require('bib_fonctions.php'); class Guitare { private $modele, $prix, $cordes, $remise, $son; const SON_A = 'acoustique'; const SON_EA = 'électro-acoustique'; const SON_R = 'à résonnateur'; const SON_E = 'électrique'; public function __construct($p1, $p2, $p3){ $p1 = trim($p1); if ($p1 == '') exit('Paramètre modèle invalide'); $this->modele = $p1; $ok = array(4, 6, 12); if (!estEntier($p3) || !in_array($p3, $ok)) { exit ('Paramètre nombre de cordes invalide'); } $this->cordes = $p3; $this->setPrix($p2); $this->remise = 0; } public function setPrix($val) { if (!is_numeric($val) || $val < 0) { exit ('Valeur de prix invalide'); } $this->prix = $val; } public function decrire() { echo '<h4>Instance de la classe ', __CLASS__, '</h4>', $this->modele, '<br>', $this->cordes, ' cordes<br>', $this->prix, ' &euro;'; } } // Fin de la classe Guitare htmlDebut('Définition de constantes'); htmlInfo('Voir la définition des constantes dans le code'); htmlFin(); ?>

### Utiliser des constantes, résolution de portée

On NE PEUT PAS pas utiliser l'opérateur `->` avec une constante.

Pour faire référence à une constante de classe dans notre code, nous devons utiliser l'opérateur `::` (double deux-points). L'opérateur `::` est également appelé opérateur de résolution de portée.

Suivant l'endroit du code où on fait référence à la constante, l'opérateur de portée est précédé :
- du mot-clé `self`,
- du nom de la classe, - de la variable instance de la classe.

utiliser une constante avec l'opérateur de portée
Exemple : utilisation de constantes
<?php ob_start(); require('bib_fonctions.php'); class Guitare { private $modele, $prix, $cordes, $remise, $son; const SON_A = 'acoustique'; const SON_EA = 'électro-acoustique'; const SON_R = 'à résonnateur'; const SON_E = 'électrique'; public function __construct($p1, $p2, $p3, $p4) { $p1 = trim($p1); if ($p1 == '') exit('Paramètre modèle invalide'); $this->modele = $p1; $ok = array(4, 6, 12); if (!estEntier($p3) || !in_array($p3, $ok)) { exit ('Paramètre nombre de cordes invalide'); } $this->cordes = $p3; $this->setPrix($p2); if ($p4 == self::SON_A || $p4 == self::SON_EA || $p4 == self::SON_R || $p4 == self::SON_E) { $this->son = $p4; } else { exit ('Paramètre son invalide'); } $this->remise = 0; } public function setPrix($val) { if (!is_numeric($val) || $val < 0) { exit ('Valeur de prix invalide'); } $this->prix = $val; } public function decrire() { echo '<h4>Instance de la classe ', __CLASS__, '</h4>', $this->modele, ' - ', $this->son, '<br>', $this->cordes, ' cordes<br>', $this->prix, ' &euro;'; } } // Fin de la classe Guitare htmlDebut('Utilisation de constantes'); htmlInfo('Les constantes son de la classe Guitare'); echo Guitare::SON_A, '<br>'; echo Guitare::SON_EA, '<br>'; echo Guitare::SON_R, '<br>'; echo Guitare::SON_E; $g1 = new Guitare('Guild D120', 639, 6, Guitare::SON_A); $g1->decrire(); $g2 = new Guitare('Dobro Hound Dog', 453, 6, Guitare::SON_R); $g2->decrire(); htmlFin(); ?>

### Exercice : constantes de classe

Reprenez le code de la classe `Livre` ci-dessous et utilisez des constantes de classe pour gérer les 4 catégories de livre possibles ("Méthode", "Partition", "Biographie" ou "Autre").

    // Définition de la classe Livre
    class Livre {
    	private $titre, $auteur, $pages, $prix, $cat;

    	public function __construct($p1, $p2, $p3, $p4, $p5) {
    		$this->titre = $this->verifChaine($p1, 'titre');
    		$this->auteur = $this->verifChaine($p2, 'auteur');
    		if (is_numeric($p3) && estEntre($p3, 10, 1000)) {
    			$this->pages = $p3;
    		} else {
    			$this->afficheErreur($p3, 'pages');
    		}
    		if (is_numeric($p4) && estEntre($val, 0, 1000)) {
    			$this->prix = $p4;
    		} else {
    			$this->afficheErreur($p4, 'prix');
    		}
    		$oks = array('Méthode', 'Partition',
    					 'Biographie', 'Autre');
    		if (in_array($p5, $oks)) {
    			$this->cat = $p5;
    		} else {
    			$this->afficheErreur($p5, 'cat');
    		}
    	}
    	private function verifChaine($val, $attr) {
    		$val = trim($val);
    		($val == '') && $this->afficheErreur($val, $attr);
    		return $val;
    	}
    	private function afficheErreur($val, $attr) {
    		exit("<hr>Valeur '<b>$val</b>' invalide pour
    				l'attribut <b>$attr</b>.<hr>");
    	}
    	public function decrire() {
    		echo '<h4>Instance de la classe Livre</h4>',
    				$this->titre, ' - ', $this->auteur, ' - ',
    				$this->pages, ' pages - ',
    				$this->prix, ' &euro; - ', $this->cat, '<hr>';
    	}
    }			// Fin de la classe Livre

Vous devez instancier 4 livres avec les informations suivantes :

Titre | Auteur | Nb Pages | Prix | Cat.
Débutant Guitare Acoustique | Rébillard | 70 | 17 | Méthode
Les accords de guitare | Carpentier | 160 | 4.90 | Autre
Guitar Play Along Neil Young | Leonard | 50 | 21.90 | Partition
50 rock songs | Piat | 120 | 19.99 | Rock

Une solution possible

Exercice : constantes de classe
<?php ob_start(); require('bib_fonctions.php'); // Définition de la classe Livre class Livre { const CAT_METHODE = 'Méthode'; const CAT_PARTITION = 'Partition'; const CAT_BIO = 'Biographie'; const CAT_AUTRE = 'Autre'; private $titre, $auteur, $pages, $prix, $cat; public function __construct($p1, $p2, $p3, $p4, $p5) { $this->titre = $this->verifChaine($p1, 'titre'); $this->auteur = $this->verifChaine($p2, 'auteur'); if (is_numeric($p3) && estEntre($p3, 10, 1000)) { $this->pages = $p3; } else { $this->afficheErreur($p3, 'pages'); } if (is_numeric($p4) && estEntre($val, 0, 1000)) { $this->prix = $p4; } else { $this->afficheErreur($p4, 'prix'); } $oks = array(self::CAT_METHODE, self::CAT_PARTITION, self::CAT_BIO, self::CAT_AUTRE); if (in_array($p5, $oks)) { $this->cat = $p5; } else { $this->afficheErreur($p5, 'cat'); } } private function verifChaine($val, $attr) { $val = trim($val); ($val == '') && $this->afficheErreur($val, $attr); return $val; } private function afficheErreur($val, $attr) { exit("<hr>Valeur '<b>$val</b>' invalide pour l'attribut <b>$attr</b>.<hr>"); } public function decrire() { echo '<h4>Instance de la classe Livre</h4>', $this->titre, ' - ', $this->auteur, ' - ', $this->pages, ' pages - ', $this->prix, ' &euro; - ', $this->cat, '<hr>'; } } // Fin de la classe Livre htmlDebut('Constantes de classe'); $livre1 = new Livre('Débutant Guitare Acoustique', 'Rébillard', 70, 17, Livre::CAT_METHODE); $livre1->decrire(); $livre2 = new Livre('Les accords de guitare', 'Carpentier', 160, 4.90, Livre::CAT_AUTRE); $livre2->decrire(); $livre3 = new Livre('Guitar Play Along Neil Young', 'Leonard', 50, 21.90, Livre::CAT_PARTITION); $livre3->decrire(); $livre4 = new Livre('50 rock songs', 'Piat', 120, 19.99, 'Rock'); // Pour test //$livre4 = new Livre('50 rock songs', 'Piat', 120, 19.99, Livre::CAT_ROCK); $livre4->decrire(); htmlFin(); ?>