- Caractères acceptés dans un champ par MySQL (Résolu) - PHP - Programmation
Marsh Posté le 30-09-2005 à 12:22:15
Pour l'apostrophe un cou de mysql_real_escape_string() devrait suffir.
Et pour les caractère spéciaux => problème de charset, changer l'interclassement, enfin il me semble...
Marsh Posté le 30-09-2005 à 13:46:02
utf8_encode
utf8_decode
mb_convert_encoding
Voilà ce qui permet de changer de codification des chaines de caractére.
pour que ca soit bien affiché dans le navigateur il faut :
Marsh Posté le 03-10-2005 à 18:53:14
dwogsi a écrit : Pour l'apostrophe un cou de mysql_real_escape_string() devrait suffir. |
Avec la fonction qui décode UTF8, je me suis débarrassé des carctères illisibles en provenance des BALs Wanadoo.
Mais la fonction mysql_real_escape _string() a l'air de faire plus de mal que de bien. J'ai des apostrophes partout.
J'avais trouvé cet exemple de code contre les attaques par injection SQL :
<?php
// Protège la variable
function quote_smart($value)
{
// Stripslashes
if (get_magic_quotes_gpc()) {
$value = stripslashes($value);
}
// Protection si ce n'est pas un entier
if (!is_numeric($value)) {
$value = "'" . mysql_real_escape_string($value) . "'";
}
return $value;
}
// Connexion
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
OR die(mysql_error());
// Fabrication d'une requête sécurisée
$query = sprintf("SELECT * FROM users WHERE user=%s AND password=%s",
quote_smart($_POST['username']),
quote_smart($_POST['password']));
mysql_query($query);
?>
Mais ça me met des apostrophes qui ont plutôt tendance à mettre la zone .
Marsh Posté le 04-10-2005 à 12:46:53
Le mieux, c'est de garder l'utf-8, et de jetter au feu tout ce qui est iso-8859-1, c'est 10 fois plus simple à gérer...
Marsh Posté le 04-10-2005 à 17:15:07
FlorentG a écrit : Le mieux, c'est de garder l'utf-8, et de jetter au feu tout ce qui est iso-8859-1, c'est 10 fois plus simple à gérer... |
Je suppose qu'il y a une instruction à mettre quelquepart pour dire qu'on bosse en utf8, plutôt que de convertir chaque chaîne en utf8 ?
Quant à mysql_real_escape_string($value), il doit y avoir des conditions d'utilisation pour que ce soit utilisable.
J'avais cru comprendre que $toto=mysql_real_escape_string($toto); permettait de balancer $toto dans la base mysql sans se poser de questions, mais ça m'a l'air un peu plus compliqué en réalité.
Si $monChamp1 = "toto", alors avec $monChamp1 = mysql_real_escape_string($monChamp1), $monChamp1 n'est plus toto mais 'toto'.
Exemple :
$sql = "INSERT INTO `maTable` (`champ1`, `champ2`, `champ3`) VALUES ('$monChamp1', '$monChamp2', '$monChamp3')";
Ca me donne quelquechose du genre :
$sql = "INSERT INTO `maTable` (`champ1`, `champ2`, `champ3`) VALUES (''toto'', ''titi'', ''tata'')"; (avec deux ' successifs et nom le caractère " ).
Et ça, mysql n'aime pas du tout.
L'idée au départ, c'était d'éviter les propblèmes avec par exemple dans $monChamp1 cette chaîne : C'est l'heure "H" (apostrophes et doubles guillemets).
Marsh Posté le 04-10-2005 à 17:53:18
mysql_real_escape_string qui rajoute des ' ? Je vois pas comment c'est possible, ou alors t'utilises quote_smart indiqué sur php.net, mais tu l'utilises mal.
La seule chose à faire avant d'utiliser mysql_real_escape_string, si les données viennent de GET/POST ou d'un cookie, c'est un stripslashes si magic_quotes_gpc est activé (get_magic_quotes_gpc() renvoie vrai).
Marsh Posté le 04-10-2005 à 18:46:51
Bonjour,
J'ai un également un problème dans le style. J'ai créer une page qui insère des données dans une table.
Code :
|
Tout ce code fonctionne. Les infos sont stockés dans ma base. En revanche si une personne mets un accents dans son message ça ressemblera à ça:
Citation : Je suis &Atilde;&nbsp; gen&Atilde;& |
Et lorsque je demande à mon code d'afficher le contenu de la table:
Citation : Je suis à genève!? |
Voici le code qui s'occupe de l'affichage:
Code :
|
Est-ce que quelqu'un saurait comment faire???
Merci!
Marsh Posté le 04-10-2005 à 18:54:26
Heu, à quoi ca sert de protéger le contenu par htmlentities si c'est pour le déprotéger à l'affichage en utilisant html_entity_decode ?
Et comment peux tu être sur que ca sera bien décodé alors que t'as rajouter un htmlspecialchars par dessus le htmlentities ?
Es tu sur de savoir à quoi servent ces fonctions, ce qu'elles font et dans quel cas elles doivent être utilisé?
Commence déjà par utiliser ces trois fonctions comme il faut et ensuite, on vérra s'il y a toujours ce probléme.
Marsh Posté le 05-10-2005 à 18:33:45
J'ai écrit un programme pour tester ce qui passe, et pour forcer ce qui ne passe pas à passer quand même (nan mais !)
Dans un formulaire, vous entrez trois champs qui contiennent des caractères à problèmes, comme les apostrophes ou des commandes html. Cliquez sur "Envoyer". La page affiche ce qu"elle a reçu et bricole les variables pour qu'elles s'affichent correctement, ou pour qu'elles soient utilisables dans une base ou dans un fichier.
Il faut MySQL car je crée une table.
Reportez-vous au listage pour voir ce que fait au juste le programme. Améliorez-le au besoin (je débute), car c'est agaçant de devoir taper \\ pour obtenir \.
Le jeu, c'est de trouver quelle bidouille il faut faire subir à une variable suivant l'usage que l'on veut en faire.
===========================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Page de test</title>
<meta name="author" content="KiosqueC">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
<!--
.Style1 {
color: #FF0000;
font-weight: bold;
}
.Style2 {color: #0000CC}
.Style4 {color: #000099}
-->
</style>
</head>
<body>
<?php
$host = "localhost";
$login = "root";
$pass = "";
$nomBase = "test";
$nomTable = "essai";
function quote_smart($variable) {
// $variable = htmlspecialchars($variable);
$variable = htmlentities($variable);
// Si les magic_quotes ont été utilisés : Stripslashes
if (get_magic_quotes_gpc()):
$variable = stripslashes($variable);
endif;
// Protection si ce n'est pas un entier : échappe les caractères NULL \x00 \n \r \ ' " et \x1a
if (!is_numeric($variable)):
$variable = mysql_real_escape_string($variable);
endif;
return $variable;
}
if (!isset($_POST['valeur1'])):
$valeur1 = "<a href=\"http://forum.hardware.fr/hardwarefr/Programmation/Caracteres-acceptes-dans-champ-MySQL-sujet-77927-1.htm#t1214752\">Forum</a>";
else:
$valeur1 = stripslashes($_POST['valeur1']);
endif;
if (!isset($_POST['valeur2'])):
$valeur2 = "Ah que c\'est la vie \\r\\n Lili";
else:
$valeur2 = stripslashes($_POST['valeur2']);
endif;
if (!isset($_POST['valeur3'])):
$valeur3 = "Être ou ne pas être c\'est là qu\'elle est la question";
else:
$valeur3 = stripslashes($_POST['valeur3']);
endif;
$valeurRedressee1 = quote_smart($valeur1);
$valeurRedressee2 = quote_smart($valeur2);
$valeurRedressee3 = quote_smart($valeur3);
$champTable1 = "";
$champTable2 = "";
$champTable3 = "";
// Connexion au serveur MySQL
// *********************
$connect = @mysql_connect($host, $login, $pass) or die ("Connexion impossible :<br />".mysql_error());
// Création de la base si elle n'existe pas
// ****************************
$sql = "CREATE DATABASE IF NOT EXISTS ".$nomBase;
mysql_query($sql) or die ("Création de la base ".$nomBase." impossible :<br />".mysql_error());
// Sélection de la base
// ***************
mysql_select_db($nomBase, $connect) or die ("Sélection impossible :<br />".mysql_error());
// Valeurs entrées dans le formulaire
echo "Valeurs initiales<br />\n";
echo "===========<br />\n";
echo "Valeur 1 : ".$valeur1."<br />";
echo "Valeur 2 : ".$valeur2."<br />";
echo "Valeur 3 : ".$valeur3."<br />";
echo "<br />\n";
// Valeur corrigées qui seront placées dans la table MySQL
echo "Valeurs redressées par la fonction quote_smart()<br />\n";
echo "====================================<br />\n";
echo "Valeur redressée 1 : ".$valeurRedressee1."<br />";
echo "Valeur redressée 2 : ".$valeurRedressee2."<br />";
echo "Valeur redressée 3 : ".$valeurRedressee3."<br />";
// Suppression de la table du test précédent
// *******************************
$sql1 = "DROP TABLE IF EXISTS `".$nomTable."`";
echo "<br />\n";
echo "Requête sql1 :<br />".$sql1."<br />";
@mysql_query($sql1) or die ("Suppression de la table ".$nomTable." impossible :<br />".mysql_error());
// Création de la table
// ***************
$sql2 = "CREATE TABLE `".$nomTable."`(
`champ1` varchar(150) NOT NULL default '',
`champ2` varchar(150) NOT NULL default '',
`champ3` varchar(150) NOT NULL default '',
PRIMARY KEY (`champ1`)
)";
echo "<br />\n";
echo "Requête sql2 :<br />".$sql2."<br />";
@mysql_query($sql2) or die ("Création de la table ".$nomTable." impossible :<br />".mysql_error());
// Insertion des valeurs dans la table :
// il s'agit des valeurs redressées, pas des valeurs brutes !
// ******************************************
$sql3 = "INSERT INTO `".$nomTable."` (`champ1`, `champ2`, `champ3`) VALUES ('$valeurRedressee1', '$valeurRedressee2', '$valeurRedressee3')";
echo "<br />\n";
echo "Requête sql3 :<br />".$sql3."<br />";
@mysql_query($sql3) or die ("Insertion dans la table ".$nomTable." impossible :<br />".mysql_error());
// Récupération des informations de la table
// *******************************
$sql4 = "SELECT * FROM `".$nomTable."`;";
echo "<br />\n";
echo "Requête sql4 :<br />".$sql4."<br />";
$req = mysql_query($sql4) or die ("Lecture de la table ".$nomTable." impossible :<br />".mysql_error());
echo "<br />\n";
echo "Contenu de la table :<br />\n";
echo "================<br />\n";
while ($champ = mysql_fetch_array($req)) {
$champ1 = $champ[0];
$champ2 = $champ[1];
$champ3 = $champ[2];
echo "<strong>Récupération brute des valeurs dans la table :</strong><br />\n";
echo "(Normalement, c'est ce que l'on désire afficher,<br />\n";
echo "mais ce n'est pas utilisable tel quel par un fichier.)<br />\n";
echo "Champ 1 = ".$champ1."<br />Champ 2 = ".$champ2."<br />Champ 3 = ".$champ3."<br />\n";
echo "<br />\n";
echo "<strong>Valeurs échappées par addslaches() pour réinsertion dans un fichier :</strong><br />\n";
$champTable1 = addslashes($champ1);
$champTable2 = addslashes($champ2);
$champTable3 = addslashes($champ3);
echo "Champ table 1 = ".$champTable1."<br />Champ table 2 = ".$champTable2."<br />Champ table 3 = ".$champTable3."<br />\n";
echo "<br />\n";
}
// Passage des valeurs dans un fichier
// On passe soit les valeurs redressées par la fonction quote_smart(),
// soit des champs issus de la table, après un addslashes().
// *******************************************
$contenu = $valeurRedressee1."\r\n".$champTable1."\r\n".$valeurRedressee2."\r\n".$champTable2."\r\n".$valeurRedressee3."\r\n".$champTable3;
$fichier = "exemple.txt";
if (file_exists($fichier)):
unlink($fichier);
endif;
echo "<br />\n";
echo "Création du fichier :<br />\n";
echo "===============<br />\n";
file_put_contents($fichier, $contenu); // Le fichier est rempli avec $contenu.
echo "Fichier créé : ".$fichier."<br />\n";
echo "<br />\n";
echo "Contenu du fichier :<br />\n";
echo "===============<br />\n";
$fichierEntree = fopen($fichier, "r" );
$i = 0;
while (!feof($fichierEntree)) {
$i++;
$ligne = fgets($fichierEntree,4096); // Lit une ligne entière
echo "Valeur lue : ".$ligne."<br />\n";
${"valeur$i"} = stripslashes($ligne); // Successivement $valeur1, $valeur2 et $valeur3
echo "Valeur redressée : ".${"valeur$i"}."<br />\n";
$ligne = fgets($fichierEntree,4096); // Lit une ligne entière
echo "Champ lu dans la base : ".$ligne."<br />\n";
echo "Champ lu dans la base et redressé : ".stripslashes($ligne)."<br />\n";
}
fclose($fichierEntree);
?>
<br />
<center>
<p>***************************************************************<br />
<span class="Style1">Saisissez des valeurs contenant des caractères à tester<br />
Comme des apostrophes ou des instructions html.<br>
</span><span class="Style4">Les \ isolés disparaissent à l'envoi. Il faut écrire \\ pour conserver un \ à l'arrivée.<br>
Ex. : pour obtenir \r\n, il faut entrer \\r\\n. </span></p>
<form name="ValeursRedressees" method="post" action="testCaracteres.php">
<input name="valeur1" id="valeur1" type="text" maxlength="150" size="80" value="<?=$valeurRedressee1;?>">
<span class="Style2"> Valeur1<br />
<input name="valeur2" id="valeur2" type="text" maxlength="150" size="80" value="<?=$valeurRedressee2;?>">
Valeur2<br />
<input name="valeur3" id="valeur3" type="text" maxlength="150" size="80" value="<?=$valeurRedressee3;?>">
Valeur3</span><br />
<input type="submit" value="Envoyer">
</form>
<br />***************************************************************<br />
<span class="Style1">la même chose, mais au lieu d'entrer les valeurs redressées<br />
on entre les valeurs issues de la table et échappées par addslashes().</span>
<form name="champsFichier" method="post" action="testCaracteres.php">
<input name="valeur1" id="valeur1" type="text" maxlength="150" size="80" value="<?=$champTable1;?>">
<span class="Style2"> Valeur1<br />
<input name="valeur2" id="valeur2" type="text" maxlength="150" size="80" value="<?=$champTable2;?>">
Valeur2<br />
<input name="valeur3" id="valeur3" type="text" maxlength="150" size="80" value="<?=$champTable3;?>">
Valeur3</span><br />
<input type="submit" value="Envoyer">
</form>
</center>
</body>
</html>
Marsh Posté le 07-10-2005 à 14:29:48
En résumé :
Dans un formulaire, je tape normalement mon texte. Sauf si je dois entrer un \. Dans ce cas je le double si c'est une entrée manuelle, sinon j'utilise la fonction addslashes()..
Quand je lis un formulaire, j'applique la fonction stripslashes() à la variable récupérée.
Avant d'entrer une variable dans une table MySQL, je lui applique la fonction quote_smart() dont le code est inclus dans mon post précédent.
Quand je récupère une valeur depuis une table, elle est directement utilisable. Elle ne peut pas s'exécuter car la fonction quote_smart() a neutralisé les commandes.
Si je veux repasser cette valeur dans un fichier, je lui applique la fonction addslashes().
Quand je la récupère, je lui applique la fonction stripslashes().
Pas testé dans mon programme ci-dessus, le passage d'une variable non extraite d'une table vers un fichier. Je pense qu'il faut lui appliquer quote_smart() pour éviter les insertions malveillantes. Et peut-être addslashes() également ?
Toujours preneur de solutions plus élégantes ou de rectificatifs.
Marsh Posté le 07-10-2005 à 15:07:06
Pour une base MySQL, quote_smart à l'envoi, htmlentities/htmlspecialchars à la relecture, et ça suffit largement.
Marsh Posté le 30-09-2005 à 12:14:03
J'ai un problème récurrent, pour lequel j'aimerais avoir une solution plus élégante que des corrections au coup par coup.
Je stocke dans une table des données, qui peuvent être des noms d'utilisateurs, des mots de passe, des noms de fichier, des URL, et des phrases, par exemple des questions posées par un utilisateur.
Je rentre ces données dans la table correspondante avec un script php, et les ennuis commencent.
Par exemple, si je dois entrer ceci dans un champ :
Le fond de l'air est frais
MysQL rouspète, à cause de l'apostrophe.
Il ne faut pas non plus que l'utilisateur s'amuse à entrer une instruction dans sa phrase, qui s'exécutera quand je chargerai le contenu de la table dans une page php.
Pour l'instant, je rectifie les caractères au coup par coup, au risque d'en oublier.
Y a-t-il un script pour n'entrer dans une table que ce qui va bien ?
Comment neutraliser une commande entrée dans un champ pour qu'elle ne puisse pas s'exécuter une fois le champ réinjecté dans une page php ?
-------------
Question subsidiaire : je récupère des messages en provenance de Wanadoo. Dans la BAL, ils sont lisibles. Une fois récupérées dans ma page PHP, j'ai des codes du genre Ã@ à la place des caractères accentués. Y a-t-il un script tout fait pour redresser cela ? J'ai écrit ceci, mais je trouve cela lourdingue (et peut-être bourré d'erreurs) :
// Rendre lisibles les caractères accentués
$carSpeciaux = array("à" => "À", "à" => "Á", "à" => "Â", "à" => "Ã", "à" => "Ä", "à " => "Å", "à" => "Æ", "à" => "Ç", "à" => "È", "à" => "É", "à" => "Ê", "à" => "Ë", "à" => "Ì", "à" => "Í", "à" => "Î", "à" => "Ï", "à" => "Ñ", "à" => "Ò", "à" => "Ó", "à" => "Ô", "à" => "Õ", "à" => "Ö", "à" => "Ù", "à" => "Ú", "à" => "Û", "à" => "Ü", "à" => "Ý", "Ã" => "à", "à¡" => "á", "â" => "â", "à£" => "ã", "à¤" => "ä", "à¥" => "å", "à¦" => "æ", "ç" => "ç", "a¨" => "è", "è" => "è", "é" => "é", "ê" => "ê", "à«" => "ë", "à¬" => "ì", "à" => "í", "î" => "î", "ï" => "ï", "à±" => "ñ", "à²" => "ò", "à³" => "ó", "ô" => "ô", "àµ" => "õ", "à¶" => "ö", "ù" => "ù", "àº" => "ú", "û" => "û", "ü" => "ü", "འ" => "ý", "Å" => "OE", "Å" => "", "â¬"=> "" );
// Utilisation :
$toto = strtr($nomDuSondage, $carSpeciaux);
Message édité par Kiosquec le 06-10-2005 à 10:51:36