Developpez.com - PHP
X

Choisissez d'abord la catégorieensuite la rubrique :

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);
}

?>
 

Valid XHTML 1.1!Valid CSS!

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'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Contacter le responsable de la rubrique PHP