Accueil > Partage de connaissances > Guides techniques > Gérer les données textuelles entre HTML (...)
 Version imprimable

Guides techniques
Programmation PHP
Gérer les données textuelles entre HTML et SGBD

Gérer une simple chaîne de texte ne pose pas de problème particulier, tant pour sa conservation en base de données que pour son affichage dans une page Web. Les choses se corsent dès lors qu’il s’agit un bloc de texte : comment conserver les retours à la ligne, les caractères spéciaux et les symboles de ponctuation ? Autre point important si votre site est accessible depuis l’Internet et qu’il permet à un visiteur de saisir un texte par le biais d’une fonction de type ’forum’ ou ’suggestion’ : comment éviter d’être victime d’un reroutage sauvage vers un site aux intentions malveillantes ?
Tous ces points seront abordés dans ce qui suit, sans prétention d’être LA solution mais un simple retour d’expérience : n’hésitez donc pas à me faire part de vos propres réflexions ou suggestions !

dimanche 11 juillet 2004, par Richard BONMARIN

Comprendre ce qui distingue la présentation HTML du stockage SGBD

Prenons l’exemple d’un texte multiligne décrivant la balise HTML "<A>" :

Exemple
La balise HTML "<A ...>" permet de définir un lien hypertexte entre deux pages, mais constitue également un repère pour les liens à l'intérieur d'une même page.
Exemples :
<A HREF="http://www.bonmarin.net">Lien vers un site au hasard</A>
<A NAME='note02'>Note 02</A>

Maintenant, posez-vous les questions suivantes :
- le texte contient des apostrophes simples et doubles : comment faire pour qu’elles ne perturbent pas la cohérence de la requête SQL destinée à enregistrer cette information dans la base de données tout en étant conservées ?
- Si ce texte peut être créé ou modifié depuis l’Internet (un site Wiki, par exemple), comment se protéger d’une saisie malveillante couramment nommée "injection de code SQL" ?
- Comment restituer ce texte sans que les balises HTML ne soient traitées comme telles par le navigateur afin d’éviter un reroutage sauvage ?

La restitution au format HTML d’un texte issu d’une base de données pose également son lot de problèmes selon que ce texte est destiné à un champ de formulaire ou un simple affichage. Ainsi, les caractères définissant un retour à la ligne devront être présentés différemment : tels quels pour un champ de formulaire, mais convertis en balises HTML "<BR/>" pour un simple affichage.

On le voit, un texte relativement complexe devra faire l’objet d’un traitement avant sa conservation en base de données, puis d’un autre pour l’affichage après extraction de la base.

Vous vous en doutez, PHP fournit des fonctions pour le traitement des chaînes de caractères qui permettront de répondre à ces interrogations.

Maintenant, passons aux choses sérieuses : comment faire ?

Traiter les données issues d’un formulaire HTML

Le contrôle de validité des variables issues du formulaire

Il est important - voire essentiel - de s’assurer que les données attendues sont bien présentes et conformes aux structures prévues. Ce contrôle d’existence et de validité fait, lui aussi, l’objet d’un article spécifique que je vous invite à consulter.

La gestion des apostrophes

Si le texte saisi dans le champ HTML contient des apostrophes, sachez que le navigateur les aura fait précéder chacune d’un caractère d’échappement sous forme d’un antislash "\" avant de le présenter au script PHP. MySQL est un SGBD qui s’accommode parfaitement de ce dispositif, mais pas SYBASE ou MS SQL : si ces derniers sont configurés pour supporter les "magic quotes", il suffira de remplacer chaque antislash par une nouvelle apostrophe.

N’ayant pas de serveur ORACLE à ma disposition, je ne sais pas dire comment ce SGBD se comporte...

La gestion des caractères spéciaux

Les caractères spéciaux les plus répandus sont les chevrons gauche "<" et droit ">" ainsi que l’esperluette "&". Ces caractères n’imposent pas de traitement particulier dans le sens HTML -> SQL.

La gestion des dates

La gestion des dates est un sujet suffisamment complexe pour mériter un article à part entière : merci de vous y reporter si vous n’en avez pas encore pris connaissance.

Gérer la destination des données

Quand un script PHP est activé pour traiter les données d’un formulaire, deux issues sont possibles :
- toutes les données du formulaire sont valides : on les enregistre en base de données puis on retourne une page de confirmation HTML,
- au moins une des données du formulaire est invalide : il est retourné en l’état, accompagné d’un message d’erreur.

Préparer les données du formulaire HTML pour SQL

Si un champ de type TEXTE contient une apostrophe, celle-ci sera automatiquement précédée d’un caractère d’échappement, celui-ci prenant la forme d’un antislash "\". En fonction du SGBD cible, il sera ou pas nécessaire de remplacer cet antislash dans la chaine de caractères lors de la construction de la requête SQL.

Si votre SGBD est MS-SQL ou SYBASE, vous devrez remplacer chaque antislash suivi d’une apostrophe par une nouvelle apostrophe. L’instruction ci-dessous vous montre comment réaliser facilement cette opération.

Exemple
$magiq_sql = str_replace("\'","''",$initial_sql);

Préparer les données du formulaire HTML pour un affichage HTML simple

Trois éléments doivent faire l’objet d’un traitement particulier : les caractères d’échappement, les caractères spéciaux et les retours à la ligne des textes multilignes.

Pour afficher un texte issu d’un champ de formulaire de type texte, il vous faudra :
- supprimer les caractères d’échappement insérés automatiquement par le navigateur,
- convertir les caractères spéciaux sous une forme affichable en toutes circonstances. Ainsi, le chevron droit ">" sera-t’il remplacé par "&gt;", le gauche "<" par "&lt;" et l’esperluette "&" par "&amp;".
- remplacer chaque éventuel retour à la ligne par une balise HTML "<br/>".

Fort heureusement, PHP fournit une fonction pour chacune de ces tâches, respectivement : stripslashes(), htmlspecialchars() et nl2br(). Vous pouvez les combiner dans l’ordre qui vous convient.

Exemple
$HTML_texte = nl2br(htmlspecialchars(stripslashes($FORM_texte)));

Traiter les données issues du SGBD

Une fois les données enregistrées en base de données ou dans un fichier, elles devront pouvoir être affichées soit pour consultation, soit pour modification.

L’affichage pour consultation consiste à présenter les données au format HTML, tandis que l’affichage pour modification consiste à traiter ces mêmes données pour définir les paramètres VALUE des champs d’un formulaire HTML.

Préparer les données SQL pour un affichage HTML simple

De par la construction de la requête SQL, les éventuelles apostrophes ont été enregistrées en base de données sans les caractères d’échappement associés ; il n’y a donc pas lieu d’effectuer un quelconque traitement pour ces derniers.

En revanche, les caractères spéciaux devront toujours être traduits en leur équivalent HTML, sauf dans le cas particulier d’un champ portant un lien hypertexte : pour que celui-ci soit actif, il ne faut pas traduire les caractères spéciaux.

Quant aux retours à la ligne, ils devront être traduits en leur équivalent HTML pour respecter la structure du texte original.

Exemple
$HTML_texte = nl2br(htmlspecialchars($SQL_texte));

Préparer les données SQL pour un formulaire HTML

Les caractères d’échappement des apostrophes ayant fait leur office juqu’à l’enregistrement en base de données, il faut recréer les antislashes afin de ne pas perturber le navigateur Web lors de son analyse du paramètre VALUE du champ de la balise HTML "<INPUT TYPE='TEXT'...>".

Exemple
$FORM_texte = addslashes(htmlspecialchars($SQL_texte));

Un texte multiligne étant encadré par les balises "<TEXTAREA> ... </TEXTAREA>", il n’est pas indispensable de restaurer les caractères d’échappement : à vous de décider si vous souhaitez appliquer ou pas un traitement unique et commun à toutes vos données de type texte.

Dans tous les cas, vous aurez à traduire les caractères spéciaux.

Synthèse

Un petit tableau en guise d’aide-mémoire rappelle les fonctions PHP à exploiter pour un traitement correct des données textuelles en fonction de la source et de la destination :

De (ci-dessous) vers (ci-contre)FORMSQLHTML
FORM pas de changement pas de changement pour MySQL, MagicQuotes pour MS-SQL et SYBASE stripslashes(), htmlspecialchar(), nl2br()
SQL htmlspecialchars(), addslashes() pas de changement htmlspecialchars()*, nl2br()*

Note (*) : sauf pour les champs portant un lien hypertexte à activer.


(Aucune contribution au forum)


 

© R. BONMARIN, 2003-2011