Filtres de validation, de nettoyage et drapeaux de l’extension PHP Filter

Télécharger le PDF du cours


Livret PDF du cours PHP et MySQL
Maintenant que nous avons une première idée du fonctionnement et du résultat des fonctions de l’extension filtre, il est temps de les utiliser en pratique.

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>

 

Liste et exemple d'utilisation des filtres de validation en PHP

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
email 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>

 

Liste et exemple d'utilisation des filtres de nettoyage en PHP

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>

 

Liste et exemple d'utilisation des drapeaux ou options des filtres en PHP

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].

Laisser un commentaire

© Pierre Giraud - Toute reproduction interdite - Mentions légales