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

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 filtreId (texte) du filtreId (nb) du filtreDescription
booleanFILTER__VALIDATE_BOOLEAN258Retourne 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_domainFILTER__VALIDATE_DOMAIN277Permet de vérifier qu’une donnée a bien la forme d’un nom de domaine
validate_emailFILTER__VALIDATE_EMAIL274Permet de vérifier qu’une donnée a bien la forme d’une adresse mail
floatFILTER__VALIDATE_FLOAT259Permet de vérifier qu’une donnée a bien la forme d’un nombre décimal
intFILTER__VALIDATE_INT257Permet de vérifier qu’une donnée a bien la forme d’un nombre entier
validate_ipFILTER__VALIDATE_IP275Permet 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_macFILTER__VALIDATE_MAC276Permet de vérifier qu’une donnée a bien la forme d’une adresse MAC
validate_regexpFILTER__VALIDATE_REGEXP272Permet de vérifier qu’une donnée a bien la forme d’une expression rationnelle regexp compatible Perl
validate_urlFILTER__VALIDATE_URL273Permet 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 filtreId (texte) du filtreId (nb) du filtreDescription
emailFILTER_SANITIZE_EMAIL517Supprime tous les caractères sauf les lettres, chiffres, et les caractères !#$%&’*+-=?^_`{|}~@.[]
encodedFILTER_SANITIZE_ENCODED514Applique l’encodage URL, et supprime ou encode les caractères spéciaux selon le drapeau passé
magic_quotesFILTER_SANITIZE_MAGIC_QUOTES521Applique la function addslashes() qui ajoute des antislashs pour échapper les caractères qui doivent l’être dans une chaine
number_floatFILTER_SANITIZE_NUMBER_FLOAT520Supprime tous les caractères sauf les chiffres, les signes + et – et les expressions de type exponentielle (« e ») avec un drapeau
number_intFILTER_SANITIZE_NUMBER_INT519Supprime tous les caractères sauf les chiffres et les signes + et –
special_charsFILTER_SANITIZE_SPECIAL_CHARS515Transforme 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_charsFILTER_SANITIZE_FULL_SPECIAL_CHARS522É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.
stringFILTER_SANITIZE_STRING513Supprime les balises, et supprime ou encode les caractères spéciaux en fonction du drapeau choisi
strippedFILTER_SANITIZE_STRIPPED513Ce filtre est un alias du filtre string
urlFILTER_SANITIZE_URL518Supprime tous les caractères sauf les lettres, chiffres et $-_.+!*'(),{}|\\^~[]`<>#% »;/?:@&=
unsafe_rawFILTER_UNSAFE_RAW516Ne 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 drapeauUtilisé avecDescription
FILTER_FLAG_STRIP_LOWFILTER_SANITIZE_ENCODED, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_SANITIZE_STRING, FILTER_UNSAFE_RAWSupprime les caractères dont la valeur numérique est <32.
FILTER_FLAG_STRIP_HIGHFILTER_SANITIZE_ENCODED, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_SANITIZE_STRING, FILTER_UNSAFE_RAWSupprime les caractères dont la valeur numérique est >127.
FILTER_FLAG_STRIP_BACKTICKFILTER_SANITIZE_ENCODED, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_SANITIZE_STRING, FILTER_UNSAFE_RAWSupprime les caractères « accent grave ».
FILTER_FLAG_ALLOW_FRACTIONFILTER_SANITIZE_NUMBER_FLOATAutorise un point (.) comme séparateur fractionnaire pour les nombres.
FILTER_FLAG_ALLOW_THOUSANDFILTER_SANITIZE_NUMBER_FLOAT, FILTER_VALIDATE_FLOATAutorise une virgule (,) comme séparateur fractionnaire pour les nombres.
FILTER_FLAG_ALLOW_SCIENTIFICFILTER_SANITIZE_NUMBER_FLOATAutorise un e ou un E pour la notation scientifique dans les nombres.
FILTER_FLAG_NO_ENCODE_QUOTESFILTER_SANITIZE_STRINGSi ce drapeau est présent, les guillemets simples (‘) et les doubles (« ) ne seront pas encodés.
FILTER_FLAG_ENCODE_LOWFILTER_SANITIZE_ENCODED, FILTER_SANITIZE_STRING, FILTER_SANITIZE_RAWEncode tous les caractères dont la valeur numérique est <32.
FILTER_FLAG_ENCODE_HIGHFILTER_SANITIZE_ENCODED, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_SANITIZE_STRING, FILTER_SANITIZE_RAWEncode tous les caractères dont la valeur numérique est >127.
FILTER_FLAG_ENCODE_AMPFILTER_SANITIZE_STRING, FILTER_SANITIZE_RAWEncode les &.
FILTER_NULL_ON_FAILUREFILTER_VALIDATE_BOOLEANRetourne NULL pour les valeurs booléennes non reconnues.
FILTER_FLAG_ALLOW_OCTALFILTER_VALIDATE_INTPrend 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_HEXFILTER_VALIDATE_INTPrend 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_UNICODEFILTER_VALIDATE_EMAILPermet à la partie locale de l’adresse électronique de contenir des caractères Unicode.
FILTER_FLAG_IPV4FILTER_VALIDATE_IPAutorise une adresse IP au format IPv4.
FILTER_FLAG_IPV6FILTER_VALIDATE_IPAutorise une adresse IP au format IPv6.
FILTER_FLAG_NO_PRIV_RANGEFILTER_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_RANGEFILTER_VALIDATE_IPEchoue 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_REQUIREDFILTER_VALIDATE_URLRequière de l’URL qu’elle contienne une partie schéma.
FILTER_FLAG_HOST_REQUIREDFILTER_VALIDATE_URLRequière de l’URL qu’elle contienne une partie hôte.
FILTER_FLAG_PATH_REQUIREDFILTER_VALIDATE_URLOblige URL à contenir un chemin.
FILTER_FLAG_QUERY_REQUIREDFILTER_VALIDATE_URLOblige URL à contenir une chaine de requête.
FILTER_REQUIRE_SCALAROblige la valeur à être un scalaire.
FILTER_REQUIRE_ARRAYOblige la valeur à être un tableau.
FILTER_FORCE_ARRAYSi 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