Comment gérer la terminaison du pluriel en PHP : les fonctions plurielles
Si comme moi vous êtes plutôt pédant(e) sur l’orthographe, même dans les SMS, les blogs, et surtout sur les résultats de recherche, vous aurez certainement tiqué en lisant "1 résultats trouvés", ou même "les fichiers image1.jpg ont été effacés". Il y a bien sûr la solution de contournement (s), 1 résultat(s) trouvé(s), mais ce n’est pas très élégant, surtout que puisqu’on en est à coder, autant détecter le pluriel s’il est présent.
Pour faciliter la tâche du codeur, PHP dans le cadre de cet article, mais le principe est le même quel que soit le langage, je vous propose ma collection personnelle de fonctions plurielles.
Quelles sont-elles, ces fonctions plurielles ?
Eh bien typiquement je conserve ma collection de fonctions plurielles au sein d’un fichier include, que j’inclus en tête de tous mes scripts PHP.
<?php
/**
(c) Fabien Haddadi -- Libre de droit de réutilisation
Merci de conserver le copyright ci-dessus lors du copier-coller.
*/
/*****************************************************************************/
function pluriel_s($n) {
return abs($n) >= 2 ? 's' : '';
}
/*****************************************************************************/
function pluriel_a($n) {
if ($n == 0) return "n’a";
return $n >= 2 ? 'ont' : 'a';
}
/*****************************************************************************/
function pluriel_a_la($n) {
return $n >= 2 ? 'aux' : 'à la';
}
/*****************************************************************************/
/**
e.g.
chev[al]
chev[aux]
*/
function pluriel_al($n) {
return $n >= 2 ? 'al' : 'aux';
}
/*****************************************************************************/
function pluriel_la($n) {
return $n >= 2 ? 'les' : 'la';
}
/*****************************************************************************/
function pluriel_le($n) {
return $n >= 2 ? 'les' : 'le';
}
/*****************************************************************************/
function pluriel_n($n) {
return $n >= 2 ? $n : 'aucun';
}
/*****************************************************************************/
/**
e.g.
[]autre commande
[3 ]autres commandes
*/
function pluriel_n_ou_vide($n) {
return $n >= 2 ? $n . ' ' : '';
}
/*****************************************************************************/
function pluriel_nt($n) {
return $n >= 2 ? 'nt' : '';
}
/*****************************************************************************/
function pluriel_tent($n) {
return $n >= 2 ? 'ent' : 't';
}
/*****************************************************************************/
function pluriel_tnent($n) {
return $n >= 2 ? 'nent' : 't';
}
/*****************************************************************************/
function pluriel_autre($n, $genre = 'm') {
return ( $genre == 'm'? ($n >= 2 ? "d'autres" : "un autre") : ($n >= 2 ? "d'autres" : "une autre"));
}
/*****************************************************************************/
function pluriel_est($n) {
return $n >= 2 ? 'sont' : 'est';
}
/*****************************************************************************/
function pluriel_votre($n) {
return $n >= 2 ? 's' : 'tre';
}
/**
Vous pouvez continuer ad libidum
*/
?>
Comment les utiliser ?
Toutes ces fonctions retournent des chaînes de caractères, qui sont soit des suffixes à ajouter, soit des suffixes de substitution. Dans tous les cas il suffit de les concaténer, avec l’opérateur dot . ou avec sprintf, ma fonction préférée, car plus lisible à mon avis.
Exemples :
<?php
// Exemple 1, cas trivial
$msg = sprintf("%d élément%s affiché%s", pluriel_n($nb), pluriel_s($nb), pluriel_s($nb));
/**
Exemple 2, cas facile
Soit $ListeIds une liste de numéros de commande, séparés par des virgules
e.g. $ListeIds = "1003,1017,1023";
*/
$_SESSION['message'] = sprintf("J'ai validé %s commande%s n°%s",
pluriel_la($n = str_word_count($ListeIds, 0, ',')),
pluriel_s($n),
$ListeIds
);
// Dans cet exemple on aura $_SESSION['message'] = "J'ai validé les commandes n°1003,1017,1023"
/**
Exemple 3, un peu plus évolué, de par l'utilisation de "aucune" si $nb_updated est nul.
*/
$_SESSION['message'] .= sprintf("%s nom%s %s été mis à jour.",
pluriel_n($nb_updated),
pluriel_s($nb_updated),
pluriel_a($nb_updated)
);
/**
Pourrait mener à
$_SESSION['message'] .= "2 noms ont été mis à jour"
ou
$_SESSION['message'] .= "1 nom a été mis à jour"
voire même
$_SESSION['message'] .= "aucun nom n'a été mis à jour"
*/
/**
Exemple 4 : voici un cas encore un peu plus évolué, puis que si $n >= 2,
on affiche $n entre "Vos" et "autres commandes".
Soit $n le nombre de commandes (nombre entier)
*/
$warning = sprintf("Vo%s %sautre%s commande%s contien%s le même produit.",
pluriel_votre($n),
pluriel_n_ou_vide($n),
pluriel_s($n),
pluriel_s($n),
pluriel_tnent($n)
);
// Si $n == 1, $warning = "Votre autre commande contient le même produit."
// Si $n > 1 (e.g. 3), $warning = "Vos 3 autres commandes contiennent le même produit."
?>
Et si j’en ai besoin en anglais ?
Les règles de la marque du pluriel sont significativement différentes. Toute quantité différente de 1 induit la prise de la marque du pluriel, même 0.
J’ai pensé à vous. Voyez plutôt ici.