Pour utiliser ces fonctions intelligemment, il va falloir renseigner le filtre qui répond à nos besoins. Il existe deux grands types de filtres : les filtres de validation et de nettoyage.
Les filtres de validation vont permettre, comme leur nom l’indique, de « valider » des données c’est-à-dire de vérifier que les données filtrées possèdent bien une certaine forme.
Les filtres de nettoyage vont eux nous permettre de « nettoyer » des données, c’est-à-dire par exemple de supprimer certains caractères non voulus comme des caractères spéciaux.
Dans cette leçon, nous allons présenter les différents filtres disponibles dans chaque groupe et également illustrer le comportement de certains d’entre eux à travers différent exemples.
Nous allons également présenter et utiliser les options et les drapeaux des filtres qui vont nous servir à préciser ou à modifier le comportement par défaut d’un filtre.
Les filtres de validation
Les filtres de validation vont nous permettre de vérifier qu’une certaine donnée possède une forme conforme à ce qu’on attend. Ces filtres se basent sur des règles de validation précises et parfois complexes qui sont issues de certaines normes. Le filtre de validation de mail, par exemple, va notamment vérifier qu’une donnée possède bien un caractère « @ » entre autres.
Nous allons pouvoir utiliser les filtres de validation suivants :
Nom du filtre | Id (texte) du filtre | Id (nb) du filtre | Description |
---|---|---|---|
boolean | FILTER__VALIDATE_BOOLEAN | 258 | Retourne true pour « 1 », « true », « on » et « yes » et false sinon. De fait, s’utilise souvent avec le drapeau FILTER_NULL_ON_FAILURE qui fait que le filtre ne retournera false que pour « 0 », « false », « off » et « no » et NULL pour toutes les autres valeurs non booléennes. |
validate_domain | FILTER__VALIDATE_DOMAIN | 277 | Permet de vérifier qu’une donnée a bien la forme d’un nom de domaine |
validate_email | FILTER__VALIDATE_EMAIL | 274 | Permet de vérifier qu’une donnée a bien la forme d’une adresse mail |
float | FILTER__VALIDATE_FLOAT | 259 | Permet de vérifier qu’une donnée a bien la forme d’un nombre décimal |
int | FILTER__VALIDATE_INT | 257 | Permet de vérifier qu’une donnée a bien la forme d’un nombre entier |
validate_ip | FILTER__VALIDATE_IP | 275 | Permet de vérifier qu’une donnée a bien la forme d’une adresse IP. S’utilise souvent avec les drapeaux FILTER_FLAG_IPV4 ou FILTER_FLAG_IPV6 pour valider une IPv4 ou une IPv6 spécifiquement |
validate_mac | FILTER__VALIDATE_MAC | 276 | Permet de vérifier qu’une donnée a bien la forme d’une adresse MAC |
validate_regexp | FILTER__VALIDATE_REGEXP | 272 | Permet de vérifier qu’une donnée a bien la forme d’une expression rationnelle regexp compatible Perl |
validate_url | FILTER__VALIDATE_URL | 273 | Permet de vérifier qu’une donnée a bien la forme d’une URL |
Illustrons immédiatement le fonctionnement de ces filtres grâce à quelques exemples concrets d’application.
<!DOCTYPE html> <html> <head> <title>Cours PHP & MySQL</title> <meta charset="utf-8"> <link rel="stylesheet" href="cours.css"> </head> <body> <h1>Titre principal</h1> <?php $tb = [ 10, 2.5, 'pierre.giraud@edhec.com', 'https://www.pierre-giraud.com', 'Pierre' ]; foreach($tb as $valeur){ echo '"' .$valeur. '" a la forme d\'un nombre entier ? : '; var_dump(filter_var($valeur, FILTER_VALIDATE_INT)); echo '<br>"' .$valeur. '" a la forme d\'un nombre décimal ? : '; var_dump(filter_var($valeur, FILTER_VALIDATE_FLOAT)); echo '<br>"' .$valeur. '" a la forme d\'un mail ? : '; var_dump(filter_var($valeur, FILTER_VALIDATE_EMAIL)); echo '<br>"' .$valeur. '" a la forme d\'une URL ? : '; var_dump(filter_var($valeur, FILTER_VALIDATE_URL)); echo '<br><br>'; } ?> <p>Un paragraphe</p> </body> </html>
Ici, on commence par créer un tableau numéroté qui stocke 5 valeurs. Nous allons déjà filtrer les valeurs de notre tableau en utilisant filter_var()
(puisque les données sont ici internes = définies dans notre script) et différents filtres de validation.
Pour cela, on crée une boucle foreach
qui va parcourir notre tableau. Pour chaque valeur du tableau, on va utiliser successivement 4 filtres qui sont les filtres int
, float
, validate_email et validate_url
.
On choisit ici de passer leur id sous forme de texte à filter_var()
mais on aurait aussi bien pu passer leur id numéroté. Si la validation réussit, la fonction filter_var()
renvoie la donnée filtrée et dans le cas contraire renvoie false
.
On utilise ici var_dump()
en lui passant le résultat de filter_var()
pour afficher finalement si la validation a réussi ou si elle a échoué.
Les filtres de nettoyage
Les filtres de nettoyage permettent de « préparer » des données en les nettoyant. Ils vont par exemple nous servir à nous débarrasser de certains caractères non souhaités lors de la réception de données et donc d’obtenir au final des données assainies qu’on va pouvoir manipuler et toute sécurité.
Les filtres de nettoyage sont donc bien différents des filtres de validation puisqu’à la différence de ces derniers ils ne vont pas nous permettre de valider la forme d’une donnée mais plutôt de modifier la forme des données reçues en suivant certains schémas qui vont dépendre du filtre utilisé.
Notez bien que les filtres de validation et les filtres de nettoyage sont souvent utilisés conjointement. On va par exemple pouvoir commencer par nettoyer une donnée reçue puis ensuite valider la forme de la donnée après nettoyage (nous verrons cela plus en détail dans la prochaine leçon).
Nous allons pouvoir utiliser les filtres de nettoyage suivants :
Nom du filtre | Id (texte) du filtre | Id (nb) du filtre | Description |
---|---|---|---|
FILTER_SANITIZE_EMAIL | 517 | Supprime tous les caractères sauf les lettres, chiffres, et les caractères !#$%&’*+-=?^_`{|}~@.[] | |
encoded | FILTER_SANITIZE_ENCODED | 514 | Applique l’encodage URL, et supprime ou encode les caractères spéciaux selon le drapeau passé |
magic_quotes | FILTER_SANITIZE_MAGIC_QUOTES | 521 | Applique la function addslashes() qui ajoute des antislashs pour échapper les caractères qui doivent l’être dans une chaine |
number_float | FILTER_SANITIZE_NUMBER_FLOAT | 520 | Supprime tous les caractères sauf les chiffres, les signes + et – et les expressions de type exponentielle (« e ») avec un drapeau |
number_int | FILTER_SANITIZE_NUMBER_INT | 519 | Supprime tous les caractères sauf les chiffres et les signes + et – |
special_chars | FILTER_SANITIZE_SPECIAL_CHARS | 515 | Transforme en entité HTML les caractères ‘ »<>& et les caractères ASCII de valeur inférieur à 32, et supprime ou encode les autres caractères spéciaux selon le drapeau choisi |
full_special_chars | FILTER_SANITIZE_FULL_SPECIAL_CHARS | 522 | Équivaut à appeler la fonction htmlspecialchars() qui convertit les caractères spéciaux en entités HTML avec ENT_QUOTES défini. ENT_QUOTES est un drapeau de htmlspecialchars() qui permet à la fonction de convertir les guillemets doubles et les guillemets simples. |
string | FILTER_SANITIZE_STRING | 513 | Supprime les balises, et supprime ou encode les caractères spéciaux en fonction du drapeau choisi |
stripped | FILTER_SANITIZE_STRIPPED | 513 | Ce filtre est un alias du filtre string |
url | FILTER_SANITIZE_URL | 518 | Supprime tous les caractères sauf les lettres, chiffres et $-_.+!*'(),{}|\\^~[]`<>#% »;/?:@&= |
unsafe_raw | FILTER_UNSAFE_RAW | 516 | Ne fait rien (par défaut) ou supprime ou encode les caractères spéciaux selon le drapeau choisi |
Attention : certains noms se ressemblent entre les filtres de nettoyage et de validation tout simplement car certains filtres vont permettre de nettoyer ou de valider une donnée de même type comme un email ou un entier par exemple.
Vous pouvez noter ici que c’est la raison pour laquelle certains filtres de validation possèdent « validate » dans leur nom : tout simplement car le nom simple était déjà pris par un filtre de nettoyage. Faites donc bien attention à ne pas confondre les différents noms !
Utilisons immédiatement quelques filtres de nettoyage pour nettoyer une chaine de caractères par exemple :
<!DOCTYPE html> <html> <head> <title>Cours PHP & MySQL</title> <meta charset="utf-8"> <link rel="stylesheet" href="cours.css"> </head> <body> <h1>Titre principal</h1> <?php $texte = 'Je suis <strong>Pierre</strong>. J\'ai 29 ans & vous ?'; echo $texte. '<br>'; echo filter_var($texte, FILTER_SANITIZE_NUMBER_INT). '<br>'; echo filter_var($texte, FILTER_SANITIZE_SPECIAL_CHARS). '<br>'; echo filter_var($texte, FILTER_SANITIZE_FULL_SPECIAL_CHARS). '<br>'; echo filter_var($texte, FILTER_SANITIZE_STRING). '<br>'; ?> <p>Un paragraphe</p> </body> </html>
Notre chaine de caractères possède ici des balises HTML, ainsi que des caractères spéciaux et des caractères « chiffres ». On commence déjà par echo
la chaine telle quelle pour voir le résultat « naturel ».
On utilise ensuite un filtre FILTER_SANITIZE_NUMBER_INT
qui va tout supprimer dans la chaine sauf les caractères chiffres, le signe + et le signe – avec notre fonction filter_var()
. Ici, pas la peine d’utiliser var_dump()
car les filtres de nettoyage vont quasiment toujours renvoyer des valeurs et on va donc plutôt directement echo
le résultat qui est le nombre 29 trouvé dans notre chaine.
Nos deuxième et troisième filtres FILTER_SANITIZE_SPECIAL_CHARS
et FILTER_SANITIZE_FULL_SPECIAL_CHARS
vont par défaut convertir certains caractères spéciaux HTML et les transformer en entité ce qui va nous permettre d’échapper leur signification spéciale et de les afficher tels quels. Ici, les deux filtres renvoient le même résultat et comme vous pouvez le voir les balises « strong » ont bien été échappées.
Finalement, notre dernier filtre FILTER_SANITIZE_STRING
va lui supprimer les balises HTML et encoder les autres caractères spéciaux.
Liste et utilisation des options et des drapeaux avec les filtres
Comme je vous le disais précédemment, on va également pouvoir utiliser des drapeaux ou des tableaux d’options avec la plupart de nos filtres.
Ces options et ces drapeaux vont nous permettre de modifier le comportement par défaut de nos filtres et / ou de les rendre plus ou moins strict.
Notez que les options vont devoir être passées via un tableau multidimensionnel qui devra être nommé options
.
A titre d’information, voici la liste des drapeaux disponibles avec les filtres. Il n’est évidemment pas question de les apprendre par cœur, mais il est bon d’en connaitre quelques-uns et de savoir que des drapeaux existent.
Identifiant du drapeau | Utilisé avec | Description |
---|---|---|
FILTER_FLAG_STRIP_LOW | FILTER_SANITIZE_ENCODED, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_SANITIZE_STRING, FILTER_UNSAFE_RAW | Supprime les caractères dont la valeur numérique est <32. |
FILTER_FLAG_STRIP_HIGH | FILTER_SANITIZE_ENCODED, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_SANITIZE_STRING, FILTER_UNSAFE_RAW | Supprime les caractères dont la valeur numérique est >127. |
FILTER_FLAG_STRIP_BACKTICK | FILTER_SANITIZE_ENCODED, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_SANITIZE_STRING, FILTER_UNSAFE_RAW | Supprime les caractères « accent grave ». |
FILTER_FLAG_ALLOW_FRACTION | FILTER_SANITIZE_NUMBER_FLOAT | Autorise un point (.) comme séparateur fractionnaire pour les nombres. |
FILTER_FLAG_ALLOW_THOUSAND | FILTER_SANITIZE_NUMBER_FLOAT, FILTER_VALIDATE_FLOAT | Autorise une virgule (,) comme séparateur fractionnaire pour les nombres. |
FILTER_FLAG_ALLOW_SCIENTIFIC | FILTER_SANITIZE_NUMBER_FLOAT | Autorise un e ou un E pour la notation scientifique dans les nombres. |
FILTER_FLAG_NO_ENCODE_QUOTES | FILTER_SANITIZE_STRING | Si ce drapeau est présent, les guillemets simples (‘) et les doubles (« ) ne seront pas encodés. |
FILTER_FLAG_ENCODE_LOW | FILTER_SANITIZE_ENCODED, FILTER_SANITIZE_STRING, FILTER_SANITIZE_RAW | Encode tous les caractères dont la valeur numérique est <32. |
FILTER_FLAG_ENCODE_HIGH | FILTER_SANITIZE_ENCODED, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_SANITIZE_STRING, FILTER_SANITIZE_RAW | Encode tous les caractères dont la valeur numérique est >127. |
FILTER_FLAG_ENCODE_AMP | FILTER_SANITIZE_STRING, FILTER_SANITIZE_RAW | Encode les &. |
FILTER_NULL_ON_FAILURE | FILTER_VALIDATE_BOOLEAN | Retourne NULL pour les valeurs booléennes non reconnues. |
FILTER_FLAG_ALLOW_OCTAL | FILTER_VALIDATE_INT | Prend en compte les nombres octaux précédés d’un zéro (0). Ceci ne fonctionne que pour les chiffres 0-7. |
FILTER_FLAG_ALLOW_HEX | FILTER_VALIDATE_INT | Prend en compte les nombres hexadécimaux précédés de 0x ou 0X. Ceci ne fonctionne que pour a-fA-F0-9. |
FILTER_FLAG_EMAIL_UNICODE | FILTER_VALIDATE_EMAIL | Permet à la partie locale de l’adresse électronique de contenir des caractères Unicode. |
FILTER_FLAG_IPV4 | FILTER_VALIDATE_IP | Autorise une adresse IP au format IPv4. |
FILTER_FLAG_IPV6 | FILTER_VALIDATE_IP | Autorise une adresse IP au format IPv6. |
FILTER_FLAG_NO_PRIV_RANGE | FILTER_VALIDATE_IP | Échoue la validation pour les intervalles privés IPv4: 10.0.0.0/8, 172.16.0.0/12 et 192.168.0.0/16. Échoue la validation pour les adresses IPv6 commençant par FD ou FC. |
FILTER_FLAG_NO_RES_RANGE | FILTER_VALIDATE_IP | Echoue la validation pour les intervalles IPv4 réservés : 0.0.0.0/8, 169.254.0.0/16, 127.0.0.0/8 et 240.0.0.0/4 et pour les intervalles IPv6 réservés ::1/128, ::/128, ::ffff:0:0/96 et fe80::/10. |
FILTER_FLAG_SCHEME_REQUIRED | FILTER_VALIDATE_URL | Requière de l’URL qu’elle contienne une partie schéma. |
FILTER_FLAG_HOST_REQUIRED | FILTER_VALIDATE_URL | Requière de l’URL qu’elle contienne une partie hôte. |
FILTER_FLAG_PATH_REQUIRED | FILTER_VALIDATE_URL | Oblige URL à contenir un chemin. |
FILTER_FLAG_QUERY_REQUIRED | FILTER_VALIDATE_URL | Oblige URL à contenir une chaine de requête. |
FILTER_REQUIRE_SCALAR | Oblige la valeur à être un scalaire. | |
FILTER_REQUIRE_ARRAY | Oblige la valeur à être un tableau. | |
FILTER_FORCE_ARRAY | Si la valeur est un scalaire, elle sera traitée comme un tableau avec les valeurs scalaires comme seul élément. |
Illustrons le fonctionnement des options et des drapeaux avec quelques filtres de validation. Notez bien ici qu’on va pouvoir de la même façon utiliser des options et des drapeaux avec des filtres de nettoyage.
<!DOCTYPE html> <html> <head> <title>Cours PHP & MySQL</title> <meta charset="utf-8"> <link rel="stylesheet" href="cours.css"> </head> <body> <h1>Titre principal</h1> <?php $prenom = 'Pierre'; $ipv4 = '127.0.0.1'; $x = 5; $y = 50; $options = ['options' => ['min_range' => 0, 'max_range' => 10]]; echo $prenom. ' booléen ? : '; var_dump(filter_var($prenom, 258)); // 258 = FILTER_VALIDATE_BOOLEAN echo '<br>' .$prenom. ' booléen ? : '; var_dump(filter_var($prenom, 258, FILTER_NULL_ON_FAILURE)); echo '<br><br>' .$ipv4. ' a la forme d\'une IP ? : '; var_dump(filter_var($ipv4, 275)); //275 = FILTER_VALIDATE_IP echo '<br>' .$ipv4. ' a la forme d\'une IPv4 ? : '; var_dump(filter_var($ipv4, 275, FILTER_FLAG_IPV4)); echo '<br>' .$ipv4. ' a la forme d\'une IPv6 ? : '; var_dump(filter_var($ipv4, 275, FILTER_FLAG_IPV6)); echo '<br><br>' .$x. ' entier compris entre 0 et 10 ? : '; var_dump(filter_var($x, 257, $options)); //257 = FILTER_VALIDATE_INT echo '<br>' .$y. ' entier compris entre 0 et 10 ? : '; var_dump(filter_var($y, 257, $options)); ?> <p>Un paragraphe</p> </body> </html>
On passe cette fois-ci des id de filtre numérotés à filter_var()
pour raccourcir notre écriture (j’ai mis en commentaire dans le code les équivalents en termes d’id nommé pour chaque filtre).
On commence par filtrer la valeur « Pierre » avec le filtre boolean
. Notre fonction filter_var()
renvoie false
dans le premier exemple car le filtre boolean
, utilisé sans drapeau, renvoie false
pour toute valeur différente de « 1 », « true », « on » et « yes ».
On utilise ensuite à nouveau le filtre boolean
pour filtrer la valeur de $prenom
mais avec cette fois-ci le drapeau FILTER_NULL_ON_FAILURE
. Ce drapeau va faire que le filtre boolean
renverra NULL
pour toute valeur non booléenne.
On tente ensuite de valider une adresse IP Notre variable $ipv4
stocke ici une valeur qui a la forme d’un IPv4 (IP version 4) mais pas la forme d’une IPv6.
On commence par utiliser le filtre validate_ip
sans drapeau. Le filtre va donc filtrer n’importe quelle IP. Ensuite, on retente de filtrer en utilisant le drapeau FILTER_FLAG_IPV4
qui permet de filtrer des IPv4 en particulier. Finalement, on utilise le filtre FILTER_FLAG_IPV6
qui permet de ne filtrer que des IPv6 et la filtre échoue donc.
On tente ensuite de valider deux entiers stockés dans des variables $x
et $y
et dans le cas présent on va également valider le fait que les entiers stockés se situent dans un certain intervalle.
Pour faire cela, on va utiliser un tableau d’options. Le tableau d’options utilisé est un tableau multidimensionnel nommé options
et qui va dans notre cas contenir un tableau associatif stockant les éléments min_range => 0
et max_range => 10
.
Les clefs de tableau min_range
et max_range
sont des mots clefs qui possèdent déjà un sens en PHP : ils vont servir à définir des bornes d’intervalle.
Ici, on va donc valider le fait que nos deux variables contiennent des entiers et que ces entiers se situent dans l’intervalle de valeurs [0-10].