[PHP] problème d'apostrophe

Bonjour à tous :slight_smile:

Je vous explique mon problème : J’ai un script PHP qui appelle une une valeur contenue dans un tableau de ma base SQL. Mais si le contenu d’un tableau contient le caractère (apostrophe), le résultat m’affichera une erreur.
Par exemble $titre_article = larticle => erreur
J’ai vérifié avec et sans, c’est bien ce caractère qui pose problème.
Je n’ai pas un niveau très élevé en PHP, alors je vous propose un résumé du code PHP qui affiche la requête :

Recherche dans la base SQL

$connect_db = connect();

$Req = "SELECT * FROM `article` ORDER BY id_article ".$ordre." ";

$Res=mysql_query($Req);
// recup
$Nb = mysql_num_rows($Res);

// parcours
	For ($i=1;$i<=$Nb;$i++)
	{
  $Ligne=mysql_fetch_array($Res);

  $titre_article = $Ligne["titre_article"];
}

et après un bête echo pour afficher mon résultat :

echo $titre_article;

Si quelqu’un connait la méthode pour afficher une variable qui contient l’apostrophe, merci d’avance :slight_smile:

Un petit cours de SQL s’impose : tu balances une requête SQL à mysql. Le SQL c’est un peu comme PHP : tu as dedans des chaînes de caractères, qui nécessitent d’être délimitée correctement :

SQL
[color=blue;font-weight:bold]SELECT[/color] *

FROM article WHERE titre_article = ‘Foo’
ORDER BY id_article

En php, cela donnera avec $titre_article :

mysql_query('SELECT *
FROM article
WHERE titre_article = \'' . mysql_real_escape_string($titre_article) . '\'
ORDER BY id_article');

Et en fait, dans ton cas : $ordre doit être contraint aux valeurs ASC et DESC, sinon injection possible.

Pour le reste, tu ne montre pas la bonne partie de code, donc je vois mal comment t’aider :slight_smile:

Au passage :

// recup
$Nb = mysql_num_rows($Res);

// parcours
For ($i=1;$i<=$Nb;$i++)
{
 $Ligne=mysql_fetch_array($Res);

 $titre_article = $Ligne["titre_article"];
}

Ca ne s’utilise pas comme ça, mais ainsi :

while (false !== ($Ligne = mysql_fetch_array($Res))) {
  echo $Ligne['titre_article'];
}

Et d’autres choses :

  1. C’est for, pas For. On ne met pas les instructions en majuscule, toujours en minuscule.

  2. L’apostrophe (ou single quote) ne fait pas la même chose que le guillemet (ou double quote). Voir doc pour ça.

Oui et comme le dis Blake_ch il faut “échapper” les caractères, pour cela les fonctions addslashes va rajouter un \ avant les caractères spéciaux, cela permettra par exemple à php ou mysql de savoir que c’est un caractère et non un élément de la synthaxe du langage.

gasp.

Pas addslashes. Dans le context mySQL, c’est mysql_real_escape_string. Rien ne vous dit le SGBD derrière ne suit pas les standards où pour échapper une single quote, il faut faire ‘’ et pas \’.

Tout d’abord, je vous remercie pour toutes vos réponses !
Mais je vous avoue que je suis un peu perdu là.
Sans nom, pourquoi mettre un WHERE comme ceci ?

WHERE titre_article = \'' . mysql_real_escape_string($titre_article) . '\'
ORDER BY id_article');

J’ai peut-être donné les mauvaises informations… Je vous donne la partie entière du code en question :

$ordre vaut DESC à ce moment là

$Req = "SELECT * FROM `article` ORDER BY id_article ".$ordre." ";

$Res=mysql_query($Req);

// recup
$Nb = mysql_num_rows($Res);

// parcours
	for ($i=1;$i<=$Nb;$i++)
	{
  $Ligne=mysql_fetch_array($Res);

  $id_article = $Ligne["id_article"];
  $titre_article = $Ligne["titre_article"];
  $auteur_article = $Ligne["auteur_article"];
  $article = $Ligne["article"];
  $video = $Ligne["video"];
  $affiche_article = $Ligne["affiche_article"];
     
  if ($affiche_article=="oui")
  {
  	
  	if (empty ($video) == TRUE)
  	{     
  	echo $titre_article;
  	}
  }
	}

Pour la forme, c’est comme cela que l’on m’ a appris à programmer en PHP/SQL à l’IUT…
Enfin j’irai me plaindre aux profs :na:

Merci de vos (futures) réponses !

Le WHERE n’est qu’un exemple :slight_smile:

Pour le reste, le parcours est toujours aussi stupide : pas besoin de faire un for, fait un while :slight_smile: c’est comme ça que c’est écrit dans la doc, et ça évite de faire une incrémentation inutile :slight_smile:

Une petite remarque:

tu sélectionnes une table entière alors que tu n’as besoin que d’un champ, et de plus tu ne veux que certains enregistrements, plutôt que de faire le tri en PHP, il est plus efficace et plus propre (selon moi) de le faire avec ta requête SQL

j’aurais plutôt fait :


$Req = "SELECT * FROM `article` WHERE affiche_article = 'OUI' AND video IS NULL ORDER BY id_article ".$ordre." ";

$Res=mysql_query($Req);


// parcours
while ($Ligne=mysql_fetch_array($Res))
{
   $id_article = $Ligne["id_article"];
   echo $titre_article;
}

Après, ce n’est que mon point de vue et mon avis, mais je trouve cela plus efficace et plus propre :slight_smile:

En retirant les ``, cette requête serait en effet meilleure.

Je profite de la remarque de RRMX pour lui demander : Pourquoi les retirer ? Cela permet de bien délimiter le nom de la table/vue interrogée.

Raynor> dans ce cas, il faut utiliser les ANSI Quote, ou les quotes standards, et pas le truc de mySQL. ie:

"SELECT * FROM \"article\" WHERE \"affiche_article\" = 'OUI' AND \"video\" IS NULL ORDER BY \"id_article\" ".$ordre;

Et ça sert à rien si

  1. tu mets toujours tout en minuscule ou majuscule, bien que ce soit une galère (le standard demande que tout ce qui soit pas entre quote soit mis en majuscule)
  2. tu n’as pas de caractères spéciaux
  3. tu n’as pas de champs ayant le même nom qu’un mot clef du langage (exemple: date).

OK :jap:

Ah oui effectivement, j’ai repris son code, et j’avais pas fait gaffe aux ``

oliv_f => regarde bien le code que j’ai placé plus haut, j’utilise bien plusieurs champs, mais c’est vrai que je devrais fair le tri en SQL, ca serait effectivement plus mpropre :slight_smile:

Sans nom => c’est vrai qu’un WHILE serait également plus judicieux

donc avec ce code ca marche très bien :

$Req = "SELECT * FROM article WHERE affiche_article = 'OUI' ORDER BY id_article ".$ordre." ";

$Res=mysql_query($Req);
// parcours
	while ($Ligne=mysql_fetch_array($Res))
	{
  $id_article = $Ligne["id_article"];
  $titre_article = $Ligne["titre_article"];
etc...

Si je rajoute

AND video IS NULL

plus rien ne s’affiche…

Par contre pour mon problème d’apostrophe, j’ai essayé les méthodes décrites plus haut mais ca ne marche pas…

Si dans ta base de données tu n’as pas de VIDEO a la valeur NULL, c’est normal que cela ne s’affiche pas, quand tu executes la meme requete dans ton ODBC ca donne quoi ?

Dans ma BDD, certaines cases de “vidéo” sont vides, d’autres non.
Je préferai garder la condition en PHP puisque plus bas dans mon code j’affiche quelque chose quand video n’est pas vide, et cela sans requete SQL.
Je fais la même chose avec la valeur foto, qui s’affiche à d’autres endroits.
C’est pour cela que je préfèrerai garder le PHP dans ce cas précis.

Question: quand ton champ video est vide, est ce qu’il contient la valeur “” (chaîne vide) ou la valeur NULL ? En gros, phpmyadmin t’affiche-t’il NULL en italique?

Si oui, ça explique qu’il ne trouve rien. Essaye AND video = ‘’ dans ta requête

Merci de vos réponses…
Mais je me suis pitètre mal exprimé mais je veux tout afficher, que vidéo sois vide ou non. S’il est vide, j’affiche tel code, s’il y a quelque chose j’affiche autre chose.

Mon problème actuel c’est surtout mon apostrophe… J’ai a peu près suivi vos explications, mais pas complètement… :confused: Quelqu’un aurait-il une précision ?

Difficilement :slight_smile: le code que tu as filé ne nécessite pas d’apostrophes. Si tu as une erreur, débrouille toi pour afficher la ligne où ça merde :slight_smile: (genre if (erreur()) echo FILE, ‘:’, LINE, “\n”:wink: