Utilisez les constantes de classes avec PHP

(English version)

Une constante est un “identifiant” pour faire référence à une valeur donnée qui ne peux pas changer durant l’execution d’un programme.

// index.php
define(“MAXSIZE”, 100);

// main.php
echo MAXSIZE; // output 100
echo constant(“MAXSIZE”); // output 100

Dans cet exemple on set la valeur 100 à la constante MAXSIZE, à partir de la définition et de l’exemple nous comprenons que les constantes peuvent être utilisées lorsque nous voulons manipulés des valeurs figées. À partir du moment où vous aurez besoin d’une valeur qui ne change pas vous pouvez utiliser une constante.

Il est également possible de définir des constantes de classe qui restent les mêmes et sont non modifiables, par défaut les constantes de classe sont publiques. Vous pouvez accéder à la constante de classe à partir du FQCN (nom de classe complet), de la classe elle-même ou d'une instance de classe.

ℹ️ (les constantes sont des chaînes de caractère qui peuvent être en minuscules mais par convention, nous utilisons des majuscules pour les rendre facilement identifiable)

👀👇

💡 Les constantes publiques sont très puissantes et pratiques, vous pouvez les utiliser n’importe où dans votre code. Comme ce sont des chaînes de caractères, elles rendent le code plus lisible et comme elles sont définies une seule fois, il est plus facile d’éviter les fautes de frappe.

🔧 Supposons que vous ayez une application comme medium, il existe une fonctionnalité qui marque un article comme publié à condition qu’il ne soit pas supprimé. Dans mon exemple, j’ai un model Article et un handler PublishArticleHandler responsable de marquer un Article comme publié.

❓Avez-vous vu l’erreur ?

Regardez à nouveau plus lentement…

👀 Pas encore trouvé ?

Avez-vous vu ligne 22 ?

if($article->getStatus() === 'delted') // "delted" au lieu de "deleted"

🐛 Sans tests, vous n’auriez pas pu voir cette erreur et ce genre d’erreur est commun, qui n’a pas perdu 2 heure à débugger une simple faute de frappe ? 🤯

🔐 L’utilisation de constante de classe fais gagner du temps en rendant le code plus lisible, voici une version améliorée:

(📔 Une meilleure amélioration consiste à supprimer les setters, déplacer la logique à l'intérieur du model et utiliser des enums 🌟 mais ce n'est pas le but de cet article)

🌋 Les constantes de classe publique sont conçues pour être réutilisables, la plupart du temps il vaut mieux utiliser une constante qu’une valeur codée en dur, pensez à la lisibilité, la compréhension, l’autocomplétion pour la navigation ou la modification de la valeur de la constante, la prévention des fautes de frappe…

🌟 De mon point de vue, vous devez utiliser des constantes de classe partout où vous faites référence à la valeur de celle-ci. Si vous utilisez des valeurs codées en dures il y a de fortes chances que vous oubliez de les modifier le jour où vous changez la valeur et même si vous y pensez vous aller devoir les modifier une par une alors que si vous utilisez une constante la modification via votre IDE se fera partout plus facilement.

Voici d’autres exemples :

$qb->select(‘a’)
->from(‘Article’, ‘a’)
->where(‘a.status = ‘:status’)
❌->setParameter(‘status’,'deleted');

peut-être remplacé par :

->setParameter('status', Article::DELETED);

public function isDeleted(): bool
{
❌return $this->status === 'deleted';
}

peut-être remplacé par :

return $this->status === Article::DELETED;

⚠️ À mon humble avis, le seul cas où vous ne devriez pas faire référence à une constante c’est dans vos tests, avoir la valeur codée en dure dans les tests est plus sûr et rend le test plus proche du cas d’utilisation.

L’autre cas d’utilisation où je pense qu’il n’est pas nécessaire d’utiliser la constante de classe est lorsque vous avez des status code HTTP, une chose courante que j’ai vue et que j’ai faîtes (j’avais tort 😅) est d’utiliser les constantes Symfony\Component\HttpFoundation\Responsecomme : “HTTP_OK”, “HTTP_BAD_REQUEST”, “HTTP_INTERNAL_SERVER_ERROR”…

🤔 Faîtes-moi changer d’avis mais utiliser ces constantes au lieu de “200”, “400”, “500” ajoute du bruit, de la confusion et rend votre code couplé à une bibliothèque externe pour un petit avantage.

Un autre cas d’utilisation des constantes concerne les paramètres de configuration non sensible qui ne changent jamais ou rarement, laissez-moi vous montrer un exemple dans une application Symfony.

💡Definition de la constante

final class Email
{
public const CONTACT = 'contact@smaine.me'
// other stuff
}

🎉 Utilisation dans la configuration

# config/services.yamlparameters:
contact_email: !php/const Email::CONTACT
_defaults:
bind:
$contactEmail: !php/const Email::CONTACT
# OR
$contactEmail: '%contact_email%' 😅

🎁 Vous pouvez aussi l’utiliser dans twig

# footer.hmtl.twig
<a href="mailto:{{ constant(Email::CONTACT) }}">Email Us</a>

🔥 et dans les annotations

final class Article
{
public const DELETED = 'deleted';
public const PUBLISHED = 'published';
public const DRAFT = 'draft';
public const ALL = [
self::DELETED,
self::PUBLISHED,
self::DRAFT,
];
use Symfony\Component\Validator\Constraints as Assert;final class ArticleDto
{
/**
* @Assert\Choice(choices=Article::ALL, message="Invalid status")
*/
private $status;

🙂 Pour conclure, je recommande d’utiliser des constantes si la valeur ne changes jamais ou rarement excepté dans vos tests.

Merci de m’avoir lu, n’hésitez pas à me rejoindre sur twitter ou linkedin 👋

--

--

Fullstack Developer- certified Symfony 4,5 and certified AWS Solution Architect - Freelancer - Remote Worker

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Smaine Milianni

Fullstack Developer- certified Symfony 4,5 and certified AWS Solution Architect - Freelancer - Remote Worker