Accueil
Accueil Le Club Delphi Kylix C C++ Java J2EE DotNET & C# Visual Basic Access Pascal Dev Web PHP ASP XML UML SQLSGBD Windows Linux Autres

Le filtrage et l'échappement des données en PHP 5 : introduction à la technique du Poka-Yoké

Date de publication : 5 juin 2007


II. Le Poka-Yoké
II-A. Principe
II-B. Préparons le terrain


II. Le Poka-Yoké


II-A. Principe

Pour reprendre l'exemple précédent, imaginez que l'on ait le code suivant :
echo $_GET->getHTML('test');
echo $_POST->getHTML('login');
Cela n'est pas plus complexe à écrire que la syntaxe précédente mais cela présente l'avantage énorme d'utiliser une notation objet, ce qui donne bien plus de flexibilité en amont. PHP 5 nous permet d'interdire ce type de code :
echo $_GET['test']
Le développeur est ainsi contraint à utiliser une méthode de l'objet pour en récupérer la valeur. Il nous suffit donc de donner des noms clairs à nos méthodes pour donner au développeur une idée précise de ce que contient la variable.
echo $_GET->getHTML('test'); // Convertir en entités HTML avant d'afficher
echo 'SELECT * FROM user WHERE login="'.$_POST->getSQL('login').'"'; // Échapper le SQL avant d'afficher

La méthode du Poka-Yoké se résume à contraindre le développeur à utiliser la seule voie correcte (parmi un ensemble de possibles). Ici, il faut le contraindre à utiliser des méthodes pour afficher les variables car cela l'oblige à voir (grâce au nom de la méthode) l'utilisation qu'il fait des variables : les erreurs d'inattention et les oublis sont devenus impossibles.

PHP 5 a introduit un modèle objet plus proche de celui adopté par d'autres langages, plus complet, plus intéressant et plus adapté à des problématiques complexes.

Nous allons utiliser le mécanisme d'exceptions proposé par PHP en version 5 ou ultérieure, afin de mettre en place un mini framework permettant de sécuriser les données transmises depuis (et vers) l'extérieur d'un script PHP.

Comme je l'ai dit précédemment, il nous suffit d'utiliser des Objects au lieu d'Arrays pour être en mesure de contrôler l'utilisation qui est faite des variables. Cependant, les tableaux sont très pratiques car ils permettent d'utiliser des solutions comme foreach(). PHP 5 permet de faire en sorte que nos objets se comportent comme des tableaux grâce à l'interface ArrayAccess :
class MyObject implements ArrayAccess
{
    public function offsetExists($field){...}
    public function offsetGet($field){...}
    public function offsetSet($field){...}
    public function offsetUnset($field){...}
}

La méthode qui nous intéresse le plus parmi les 4 présentées ci-dessus est offsetGet(), car elle permet d'obtenir la valeur d'une propriété de l'objet avec la même syntaxe qu'un Array. Il pourrait alors de nouveau utiliser les tableaux $_POST et $_GET directement, or c'est précisément ce que nous voulons éviter.

Ainsi, nous allons désactiver cette méthode :
public function offsetGet($field)
{
    throw new Exception($field);
}

Il ne reste plus qu'à définir les méthodes d'accès aux données.


II-B. Préparons le terrain

Il faut commencer par préparer la configuration PHP adéquate pour le Poka-Yoké.

Pour cela, utilisons les scripts suivants :
main.php
<?php

// It would be best to do this in the php.ini or .htaccess
error_reporting(E_ALL | E_STRICT);


require('functions.php');

set_error_handler('errorHandler');
set_exception_handler('exceptionHandler');


if(PHP_VERSION < 5)
{
    $message = 'Your PHP version is '.PHP_VERSION.'.'
        .' You need at least PHP 5 to run these scripts.';

    trigger_error($message, E_USER_ERROR);
}


function __autoload($class)
{
    if(strpos(strtolower($class), 'exception') === FALSE)
    {
        require('classes/'.$class.'.php');
    }
    else
    {
        require('exceptions/'.$class.'.php');
    }
}

unset($_REQUEST);

if(!ini_get('session.auto_start'))
{
    session_start();
}

?>
functions.php
<?php

function displayError($message)
{
    // Put here any visual enhancement you want (page footer, etc.)
    ?>
    <div>
        <p><span style="color: red;">Execution stopped!</span></p>
        <?php echo $message; ?>
    </div>
    <?php
    exit;
}


function exceptionHandler(Exception $exception)
{
    displayError($exception->getMessage());
}


function errorHandler($code, $string, $file, $line)
{
    $error = array_search($code, get_defined_constants(), TRUE);

    $message = '<p>'
        .'<span style="color: purple; font-weight: bold;">'.$error.'</span>'
        .' in file <span style="font-weight: bold;">'.$file.'</span>'
        .' on line <span style="font-weight: bold;">'.$line.'</span></p>';

    $message .= '<p><span style="font-style: italic;">'
        .nl2br($string).'</span></p>';

    displayError($message);
}

?>
 

Copyright ©2006 Guillaume Rossolini. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérets. Cette page est déposée à la SACD.

Vos questions techniques : forum d'entraide Accueil - Publiez vos articles, tutoriels, cours et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones. Nous contacter - Copyright 2000..2005 www.developpez.com