5.2. Zend_Filter_Input

5.2.1. Introduction

Zend_Filter_Input fournit des méthodes simples dédiées au filtrage des données passées en entrée; ces services implémentent une approche structurée et stricte du problème. Ce composant est à multiples facettes car il est adapté aux besoins de trois catégories différentes de personnes :

  • Les développeurs

    Bien que le filtrage des données passées en entrée ne sera jamais aussi facile que la solution consistant à ne rien faire, les développeurs doivent pouvoir s'assurer de l'intégrité de leurs données et ce sans avoir à ajouter de complexité inutile à leur code. Zend_Filter_Input fournit des méthodes simples adaptées aux scénarios les plus fréquents, des possibilités d'extension pour les scénarios moins courants et enfin une convention de nommage stricte qui encourage la clarté du code.

  • Les chefs de projet

    Les chefs de projet de toute catégorie qui ont besoin de contrôler un groupe important de développeurs peuvent les forcer à employer une approche structurée du problème du filtrage de données en limitant ou éliminant les possibilités d'accès aux données brutes.

  • Les auditeurs

    Les personnes qui auditent le code d'une application doivent pouvoir identifier rapidement et de manière fiable à quel moment et à quel endroit les données brutes sont employées par un développeur. Les caractéristiques du composant qui encouragent la clarté du code, facilitent aussi le travail des auditeurs en leur fournissant une distinction claire entre les différentes approches du problème du filtrage de données.

Il existe une grande variété d'approches différentes du problème du filtrage de données et il existe aussi une grande variété de possibilités offertes aux développeurs PHP. Le filtrage par liste blanche, le filtrage par liste noire, les expressions régulières, les instructions conditionnelles et certaines fonctions PHP natives sont juste quelques exemples du pot pourri du filtrage de données. Zend_Filter_Input combine toutes ces possibilités en une seule et même API au comportement cohérent et aux conventions de nommage strictes. Toutes les méthodes adhèrent à une règle simple - si les données sont valides, elles sont renvoyées sinon FALSE est renvoyé : simplicité extrême!

5.2.1.1. Filtrage par liste blanche

Les méthodes implémentant un filtrage par "liste blanche" commencent par test; testAlpha() et testEmail() en sont deux exemples. Ces méthodes inspectent les données passées en entrée selon des critères pré-définis et ne renvoient ces données que si elles adhèrent aux critères considérés. Si ce n'est pas le cas, FALSE est renvoyé. L'exemple suivant constitue une illustration simple :

        <?php

        $filtrePost = new Zend_Filter_Input($_POST);

        if ($nomAlpha = $filtrePost->testAlpha('nom')) {
            /* $nomAlpha ne contient que des caractères alphabétiques */
        } else {
            /* $nomAlpha est évalué comme FALSE */
        }

        ?>
        

L'exemple ci-dessus échoue dans certains cas du fait de l'évaluation booléenne de la valeur renvoyée par la méthode testAlpha(). Si vous voulez faire une distinction entre les valeurs évaluées comme FALSE par PHP (comme l'entier 0 ou la chaîne vide) et l'objet FALSE lui-même, vous pouvez réaliser une comparaison stricte :

        <?php

        $filtrePost = new Zend_Filter_Input($_POST);
        $nomAlpha = $filtrePost->testAlpha('nom');

        if ($nomAlpha !== FALSE) {
            /* $nomAlpha ne contient que des caractères alphabétiques */
        } else {
            /* $nomAlpha === FALSE */
        }

        ?>
        

5.2.1.2. Filtrage à l'aveugle

Les méthodes implémentant un filtrage à l'aveugle commencent par get; getAlpha() et getDigits() en sont deux exemples. Ces méthodes n'inspectent pas les données passées en entrée mais renvoient la partie considérée comme valide de ces données. À titre d'exemple, getAlpha() renvoie uniquement les caractères alphabétiques des données, s'il y en a. (S'il n'y en a pas, la chaîne sera vide.) L'exemple suivant constitue une illustration simple :

        <?php

        /* $_POST['nom_utilisateur'] = 'Jacques123Dupond'; */

        $filtrePost = new Zend_Filter_Input($_POST);
        $nomUtilisateurAlpha = $filtrePost->getAlpha('nom_utilisateur');

        /* $nomUtilisateurAlpha = 'JohnDoe'; */

        ?>
        

5.2.1.3. Filtrage par liste noire

Les méthodes implémentant un filtrage par liste noire commencent par no; noTags() et noPath() en sont deux exemples. Ces méthodes sont identiques aux méthodes de filtrage à l'aveugle sauf que le critère dont elles s'assurent représente ce qui est invalide et non valide. Les données invalides sont supprimées puis le reste (supposé valide) est renvoyé. L'exemple suivant constitue une illustration simple :

        <?php

        /* $_POST['commentaire'] = "<b>J'aime PHP!</b>"; */

        $filtrePost = new Zend_Filter_Input($_POST);
        $commentaireSansBalises = $filtrePost->noTags('commentaire');

        /* $commentaireSansBalises = "J'aime PHP!"; */

        ?>
        

5.2.2. Fonctionnement

Zend_Filter_Input combine plusieurs approches différentes du filtrage de données en une seule et même API au comportement cohérent et aux conventions de nommage strictes (voir la section Section 5.2.1, « Introduction »). Ceci met Zend_Filter_Input sur un pied d'égalité avec les solutions existantes mais cela ne facilite pas vraiment la vie des personnes qui souhaitent une approche plus structurée ou plus stricte. C'est pourquoi Zend_Filter_Input force par défaut les développeurs à accéder de manière contrôlée aux données passées en entrée.

Deux syntaxes sont prises en charge. Dans l'approche par défaut (stricte), le seul argument passé au constructeur est le tableau devant être filtré :

        <?php

        $filtrePost = new Zend_Filter_Input($_POST);
        $email = $filtrePost->testEmail('email');

        ?>
        

Zend_Filter_Input affecte NULL au tableau passé en argument ($_POST dans notre exemple) et ainsi l'accès direct aux données n'est plus possible. (Les données brutes ne sont accessibles que via la méthode getRaw(), bien plus simple à rechercher et/ou éviter.)

Pour l'approche optionnelle (non-stricte), vous devez passer FALSE en tant que deuxième argument du constructeur.

        <?php

        $filtrePost = new Zend_Filter_Input($_POST, FALSE);
        $email = $filtrePost->testEmail('email');

        ?>
        

L'utilisation est exactement la même, sauf que Zend_Filter_Input ne définit pas le tableau original ($_POST) à NULL, les développeurs peuvent donc toujours y avoir accès. Cette approche est déconseillée au profit de l'approche stricte.

Zend_Filter_Input est conçu en priorité pour fonctionner avec des tableaux. Beaucoup de sources de données sont présentes en PHP sous forme de tableaux ($_GET, $_POST,$_COOKIE, etc.) et les tableaux constituent en général un moyen courant de stocker les données provenant d'une source tierce. Si vous souhaitez filtrer un scalaire, voyez Chapitre 5, Zend_Filter.

5.2.3. Exemples d'utilisation

Filtrage strict par liste blanche (conseillé) :

        <?php

        $filtrePost = new Zend_Filter_Input($_POST);

        if ($email = $filtrePost->testEmail('email')) {
            /* $email est une adresse e-mail valide */
        } else {
            /* $email n'est pas une adresse e-mail valide */
        }

        ?>
        

Filtrage à l'aveugle strict :

        <?php

        $filtrePost = new Zend_Filter_Input($_POST);
        $nomAlpha = $filtrePost->getAlpha('nom');

        ?>
        

Filtrage strict par liste noire :

        <?php

        $filtrePost = new Zend_Filter_Input($_POST);
        $commentaireSansBalises = $filtrePost->noTags('commentaire');

        ?>
        

Filtrage non-strict par liste blanche :

        <?php

        $filtrePost = new Zend_Filter_Input($_POST, FALSE);

        if ($email = $filtrePost->testEmail('email')) {
            /* $email est une adresse e-mail valide */
        } else {
            /* $email n'est pas une adresse e-mail valide */
        }

        ?>
        

Filtrage non-strict à l'aveugle :

        <?php

        $filtrePost = new Zend_Filter_Input($_POST);
        $nomAlpha = $filtrePost->getAlpha('nom');

        ?>
        

Filtrage non-strict par liste noire :

        <?php

        $filtrePost = new Zend_Filter_Input($_POST, FALSE);
        $commentaireSansBalises = $filtrePost->noTags('commentaire');

        ?>