Steve Frécinaux

PHP: magic-quotes et GET/POST/COOKIE

Vous connaissez certainement tous la fonction set_magic_quotes_runtime, en PHP, qui permet de spécifier, au moment de l’exécution, la valeur de la propriété ini magic- quotes-runtime, qui fait en sorte que les caractères spéciaux en provenance d’une source de données externe (base de données, fichier texte) soit échappés, et qui en règle générale est particulièrement embêtante.

Par contre vous ne connaissez pas la fonction set_magic_quotes_gpc, et pour cause : elle n’existe pas.

Pourtant vous conviendrez qu’une telle fonction s’avérerait rudement pratique, car la directive magic-quotes-gpc, qui gère l’échappement des chaines fournies par le visiteur du site, via les méthodes POST, GET ou les cookies, est tout aussi contraignante lors de la phase de développement. En effet, comme cette directive change selon la configuration du serveur, il faut généralement tester sa valeur, via get_magic_quotes_gpc afin d’échapper ou de déséchapper proprement la chaine, suivant les cas et la destination de cette chaine.

Ce serait tellement plus simple s’il existait un équivalent à la première fonction !

Et bien comme elle n’existe pas, créons-la, sur le même modèle que son homoloque set_magic_quotes_runtime. Elle doit donc accepter un argument booléen, pour indiquer si l’on désire échapper ou non les tableaux concernés ($_GET, $_POST, $_COOKIE et $_REQUEST qui regroupe ces trois premiers tableaux). La fonction de base se bornera à vérifier la valeur de la directive dans le fichier de configuration, et si elle ne correspond pas à la valeur souhaitée, on traite les différents tableaux :

function set_magic_quotes_gpc($new_setting) {
   if (get_magic_quotes_gpc() == !$new_setting) {
      $_GET = set_magic_quotes_gpc_recursive($_GET, $new_setting);
      $_POST = set_magic_quotes_gpc_recursive($_POST, $new_setting);
      $_COOKIE = set_magic_quotes_gpc_recursive($_COOKIE, $new_setting);
      $_REQUEST = set_magic_quotes_gpc_recursive($_REQUEST, $new_setting);
   }
}

On teste ici que la directive est “égale à non-$new_setting” plutôt que de tester si la valeur en est différente. La raison en est simple, c’est que $new_setting peut ne pas être un booléen. Le résultat de !$new_setting, par contre, sera toujours booléen, et donc le test sera toujours valide.

Pour traiter les différents tableaux, on va utiliser une fonction récursive. En effet, il n’est pas exclu que l’une ou l’autre des valeur soit un tableau, voire même un tableau de tableaux. La fonction récursive, donc, vérifie le type de la valeur, se rappelle s’il s’agit d’un tableau, ou (dés)échappe la valeur s’il s’agit d’une chaîne.

function set_magic_quotes_gpc_recursive($value, $new_setting) {
   if (is_array($value)) {
      $return = array();
      foreach ($value as $key => $val)
         $return[$key] = set_magic_quotes_gpc_recursive($val, $new_setting);
      return $return;
   } else {
      return $new_setting ? addslashes($value) : stripslashes($value);
   }
}

Voilà, la fonction est prête. Elle peut alors être utilisée aussi simplement que la fonction qui lui a servi de modèle, au début du fichier PHP :

set_magic_quotes_gpc(false);