Dans le cadre du contrôle de saisie "côté serveur" il faut vérifier si l'adresse mail saisie à un format
correct, si le mot de passe saisi correspond au gabarit exigé, si les numéros de téléphone comprennent bien 10 chiffres, etc.
Concrétement chaque saisie est comparée à une expression régulière ou "regexp".
La fonction preg_match()
Pour vérifier si une saisie coïncide avec une regexp il faut utiliser la fonction
preg_match()
Construire une expression régulière
En PHP une regexp doit être délimitée par des # ; le # final peut être suivi d'une option.
Exemple 1
Le code du document PHP (extrait)
Examinons les différentes regexp utilisés (certains sont utilisées dans deux tests) :
#paul#: recherche de la chaine 'paul' dans la chaine ; la fonction preg_match() retourne false car
'paul' avec un p minuscule n'existe pas ! les regexp sont sensibles à la casse.
#paul#i : après le deuxième # j'ai rajouté l'option "i" qui signifie "insensible à la casse". Donc le test 2
retourne VRAI puisque la chaine comprend le mot 'PAUL'
#paul|louis# : recherce des mots 'paul' ou 'louis" avec respect de la casse donc le test 3 retourne FAUX
#paul|louis#i : recherche des mots 'paul' ou 'louis' SRC (Sans Respect de la Casse). Donc les tests 4 & 5 retournent VRAI
#bonjour#i" : recherche du mot 'bonjour' dans la chaine SRC donc le test 6 retourne VRAI.
#amis#i : à vous de trouver le commentaire et le résultat du test 7
#^bonjour#i : recherche du mot 'bonjour' en début de chaine SRC
#amis$#i : recherche du mot 'amis' en fin de chaine SRC
#^bonjour$#i : la chaine ne doit contenir que la regexp, ni plus ni moins
Pour la dernière regexp notez l'emploi des symboles ^ et $ respectivement en début et fin de regexp ;
la chaine qui lui est comparée doit coïncider strictement avec la regexp, ni plus ni moins.
Le rendu
Tous les tests retourne VRAI sauf :
test 1 : même mot mais pas la même casse
test 3 : la chaine contient un des mots possibles pas avec la même casse
dernier test : la chaine contient le mot 'bonjour' mais pas uniquement ...
Les classes et les quantificateurs
Les expressions régulières complexes sont une suite de paires classe - quantificateur
Les classes
Dans une regexp une classe est délimitée par des crochets.
À l'intérieur des crochets une suite de caractères autorisé et/ou un intervalle.
Quelques exemples de regexp avec classes :
#^[aA]# : la chaine doit commencer par une lettre A minuscule ou majuscule
#[a-z]$# : la chaine doit se terminer par une lettre minuscule
#[a-zéèê]# : la chaine ne peut comprendre que des lettres minuscules
#[A-z]# : la chaine ne peut comprendre que des lettres majuscules ou minuscules.
#[A-z0-9]# : la chaine peut comprendre des caractères alphanumériques non accentués
#[^0-9]# : tous les caractères sont autorisés sauf les chiffres
le ^ en début de classe signifie la négation.
Ne confondez pas avec le ^ en début de regexp.
Les principaux raccourcis de classe ou 'classes abrégées' :
\d équivaut à [0-9]
\D : sauf chiffres équivaut à [^0-9]
\w : n'importe quel caractère alphanumérique y compris underscore ; équivaut à [A-z0-9_]
Les quantificateurs
Dans un regexp un quantificateur est entre accolades.
Un quantificateur indique le nombre de caractères autorisés.
Quelques exemples de regexp avec une classe et le quantificateur associé :
#[a-z]{5}# : 5 lettres minuscules, ni plus ni moins !
#[@]{1}# : 1 symbole @
#[\?\#\^\$\.]{1,} : au moins un métacaractère
#[A-z]{0,1}# :0 ou 1 lettre
Attention les symboles ? # ^ $ . sont utilisés dans la syntaxe des regexp.
On les appelle les métacaractères.
Donc si vous les utilisez dans une classe il faut les échapper.
On peut exprimer plus simplement le quantificateur sous forme d'un symbole :
* : 0 à plusieur fois
+ : 1 à plusieurs fois
? : 0 à 1 fois équivaut à {0,1}
Exemple 2
Le code du document PHP (extrait)
Le rendu
Examinons quelques regexp
#[0-9 ]# : caractères autorisés : chiffres et espace.
#[A-zéè0-9: ]# : caractères autorisés : lettres dont lettres accentuées, chiffres, : et espace.
Dans les deux dernières instructions je compare le mot de passe "Sesame$59" successivement aux
regexp #[A-z0-9\?\!\$\]{8,12]# puis #[A-Z]{0,1}[a-z]{5,}[0-9]{2,}[\?\!\$\#]{1}#.
Le premier test retourne "mot de passe valide" et le deuxième "mot de passe invalide".
En effet le premier regexp n'impose par d'ordre : entre 8 et 12 lettre, chiffres et métacaractères.
Le deuxième regexp impose un ordre : une lettre Majuscule (facultatif), au moins 5 lettres minuscules,
au moins deux chiffres puis un métacaractère.
Si le contenu d'un champ correspond à son pattern alors il passe au vert.
Le code du formulaire
Le contrôle de saisie 'côté navigateur' se limite ici aux attributs pattern
Examinons la regexp associée à chaque attribut pattern :
pour le champ "email" :^\w{1,}@\w{2,}\.[A-z]{2,4}$ ; en effet une adresse mail valide comprend :
au moins un caractère alphanumériques
le symbole @
au moins deux caractères alphanumériques
le point (un métacaractère qui doit être échappé)
entre 2 et 4 lettres
et rien d'autres avant et après d'où les symboles ^ et $
pour le champ 'pseudo' : ^[a-z ]{6,10}$ ; entre 6 et lettres minuscules
pour le champ 'motpasse' : ^\w{6,8}$ ; entre 6 et 8 caractères alphanumériques
pour le champ 'tel' : ^\d{10}$ ; 10 chiffres.
Le script PHP
Mais pourquoi un contrôle de saisie côté serveur ?
Le contrôle 'côté client' n'est-il pas suffisant ?
Via les outils de développement du navigateur, un visiteur malin peut accéder au code HTML et JS et peut le modifier pour
sa session.
Ainsi, s'il est mal intentionné, il peut supprimer les attributs pattern & required pour un champ de saisie.
Il pourra alors soumissionner tout en laissant le champ vierge OU ET beaucoup plus grave, injecter un instruction HTML :
lien vers un site coquin, par exemple.
Donc le script PHP (exécuté côte serveur) doit donc vérifier si :
le tableau $_POST[] n'est pas vide
si $_POST[] n'est pas vide mais que l'une des quatre valeurs n'existe pas alors il affiche un message d'erreur.
Sinon il convertit les instructions HTML en chaines.
Ensuite il compare le contenu de chaque champ à une regexp.
Les expressions régulières dans le script PHP sont identiques à celles dans le code HTML sauf
que dans le script PHP il faut les délimiter par # afin de préciser qu'il s'agit bien de regexp alors
que dans le code HTML et pour l'attribut pattern c'est implicite.
Le rendu
Faites des bêtises, par exemple saisissez à la suite d'une adresse mail / pseudo corect ; le contenu du champ redevient rouge.
Exercice
Esssayez de reconstituer tout le code du document PHP ci-dessous.
Notez le champ qui permet de saisir la date de naissance au format JJ MM AAAA avec en guise
de séparateur / ou - ou espace.
Concevez la regEx pour ce champ à utiliser en HTML et en PHP.