Validation & Nettoyage : Une introduction au filtrage des données

Le filtrage des données est particulièrement utile lorsque les données sont issues de sources inconnues, comme celles soumises par un utilisateur utilisant un formulaire HTML. Depuis sa version 5, PHP propose toute une baterrie de fonctions permettant la validation et le nettoyage des données. De quoi dire adieu aux vilaines expressions rationnelles parfois encore utilisées pour valider nos données !

Valider et nettoyer

Il existe deux moyens de filtrer les données : la validation et le nettoyage.

La validation sert à vérifier si une donnée passe certains critères. Par exemple, le validateur FILTER_VALIDATE_EMAIL permet de déterminer si une donnée est une adresse E-Mail valide, sans pour autant nettoyer l'adresse.

Le nettoyage sert à retirer les caractères indésirables. Par exemple, le nettoyeur FILTER_SANITIZE_EMAIL permet de faire disparaître les caractères inappropriés dans une adresse E-Mail, sans pour autant valider l'adresse.

Que l'on souhaite valider ou nettoyer une donnée, on utilisera la fonction filter_var avec l'identifiant du filtre désiré. Il existe de nombreux filtres de validation et de nettoyage.

Au plus pratique

Commençons cette introduction sur les châpeaux de roues avec la présentation des deux validations les plus fréquentes : celle des adresses E-Mail et celle des URL.

Valider une adresse E-Mail

<?php

var_dump(filter_var('paul@exemple.com', FILTER_VALIDATE_EMAIL));
string(16) "paul@exemple.com"

C'est quand même beaucoup plus simple que d'utiliser l'expression rationnelle :

/^[a-z0-9._-]+@[a-z0-9.-]{2,}[.][a-z]{2,3}$/

Valider une URL

<?php

var_dump(filter_var('http://www.weirdog.com', FILTER_VALIDATE_URL));
^(https?|ftp)\:\/\/([a-z0-9+!*(),;?&=\$_.-]+(\:[a-z0-9+!*(),;?&=\$_.-]+)?@)?[a-z0-9+\$_-]+(\.[a-z0-9+\$_-]+)*(\:[0-9]{2,5})?(\/([a-z0-9+\$_-]\.?)+)*\/?(\?[a-z+&\$_.-][a-z0-9;:@/&%=+\$_.-]*)?(#[a-z_.-][a-z0-9+\$_.-]*)?\$

Validation plus poussée :

<?php

var_dump(filter_var('http://www.google.com', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED));
var_dump(filter_var('http://www.google.com/search', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED));
var_dump(filter_var('http://www.google.com', FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED));
var_dump(filter_var('http://www.google.com?q=1', FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED));
var_dump(filter_var('http://www.google.com', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED | FILTER_FLAG_QUERY_REQUIRED));
var_dump(filter_var('http://www.google.com/search?q=1', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED | FILTER_FLAG_QUERY_REQUIRED));
bool(false)
string(28) "http://www.google.com/search"
bool(false)
string(25) "http://www.google.com?q=1"
bool(false)
string(32) "http://www.google.com/search?q=1"

Au plus offrant

De nombreux autres filtres sont disponibles sont valider ou nettoyer des booléens, des entiers, des nombres à virgules, des chaines de caractères… Il est même possible de passer une expression régulière ou encore une fonction de rappel.

Voyons quelques exemples :

Valider un booléen

<?php

var_dump(filter_var('1', FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var('true', FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var('yes', FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var('on', FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var('false', FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var('0nimportequoi', FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var('0nimportequoi', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE));
bool(true)
bool(true)
bool(true)
bool(true)
bool(false)
bool(false)
NULL

Pensez à utiliser le drapeau FILTER_NULL_ON_FAILURE si vous voulez vraiment valider un booléen, sinon les valeurs qui échouent à la validation retourne false tout comme les booléens faux tels que « no », « off » ou « false ».

Valider et nettoyer un entier

<?php

var_dump(filter_var('1', FILTER_VALIDATE_INT));
var_dump(filter_var('1on', FILTER_VALIDATE_INT));
var_dump(filter_var('24', FILTER_VALIDATE_INT, array('options' => array('min_range' => 20'max_range' => 30))));
var_dump(filter_var('60', FILTER_VALIDATE_INT, array('options' => array('min_range' => 20'max_range' => 30))));
var_dump(filter_var('before1after0', FILTER_SANITIZE_NUMBER_INT));
int(1)
bool(false)
int(24)
bool(false)
int(10)

Nettoyer une chaine de caractères

<?php

var_dump(filter_var("l'été \"ici\" et là. 4 > 1 & 2", FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES));
var_dump(filter_var("l'été \"ici\" et là. 4 > 1 & 2", FILTER_SANITIZE_STRING));
var_dump(filter_var("l'été \"ici\" et là. 4 > 1 & 2", FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_AMP));
string(31) "l'été "ici" et là. 4 > 1 & 2"
string(43) "l&#39;été &#34;ici&#34; et là. 4 > 1 & 2"
string(47) "l&#39;été &#34;ici&#34; et là. 4 > 1 &#38; 2"

Conclusion

Et voici que s'achève ce petit tour des filtres de données introduits par la version 5 de PHP.

Évidement, certaines fonctionnalités peuvent paraitre redondantes. On peut se demander l'utilité des filtres FILTER_VALIDATE_REGEXP ou FILTER_CALLBACK, quand on peut directement appeler une fonction. À mes yeux, l'intéret du système de filtre est avant tout son unité. Il permet de remplacer fonctions et bouts de codes avec une API réduite, taillée pour de future extensions.

Laisser un commentaire

Pas de commentaire