8796 sujets

Développement web côté serveur, CMS

Salut,
je recherche l'erreur dans cette partie de code...

Message d'erreur:
a écrit :
Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in H:\Apps\ZMWS\_web.zmwsc\mini-forum-14-php\index.php on line 180


La partie de code concernée (en gras la partie de code désignée à la ligne 180)

$SQL1 = "SELECT $tb1.ID,reponse,$tb1.quand,login,email,titre,message,ismodo,IDuser,pied"
. " FROM $tb1 LEFT JOIN $tb2 ON $tb1.IDuser=$tb2.ID";



	// Requête de sélection des messages
	$SQL = $SQL1 . " WHERE IDtopic=".$_GET["topic"]." ORDER BY dernier DESC,ID"
		. " LIMIT ".($page-1)*$maxPosts.",".$maxPosts;
	$res = mysql_query($SQL); $i=0;
	echo "<dl><td class=msg>";
	// Tant qu'il y a des messages
	[b]while($val = mysql_fetch_array($res)) { $i++;[/b]
		$temp = "";
		// Cas où on démarre d'une réponse > on réaffiche le sujet
		if(($i==1)&&($val["reponse"]!=$val["ID"])) {
			$SQL = $SQL1 . " WHERE $tb1.ID=".$val["reponse"];
			$val=mysql_fetch_array(mysql_query($SQL));
			mysql_data_seek($res,0);
		}
		// Poubelle ? Admin ou Modérateur (sauf msg d'autres modérateurs) ou Message du visiteur
		if( $isAdmin || ($isModo&&($val["ismodo"]!="1")&&($val["IDuser"]!="1")) || ($user["ID"]==$val["IDuser"]) )
			$temp.="<A href='".$url."&del=".$val["ID"]."&page=".$page."'>".$img_poub."</A> ";
		// Edition ? Sujet du visiteur
		if(($val["reponse"]==$val["ID"])&&($user["ID"]==$val["IDuser"]))
			$temp.= "<A href='".$url."&edit=".$val["ID"]."&page=".$page."#edit'>".$img_edit."</A> ";
		// Nouveau sujet ?
		if($val["reponse"]==$val["ID"]) {
			if($i>1) echo "</td></dl></tr><tr><dl><td class=msg>";
			$temp.="<A class=msg href='".$url."&post=".$val["ID"]."'>";
		}
		// Ecrit la date du message
		$temp.="<span class=msgdate>"
			.date("d/m/y H:i",$val["quand"])." </span>";
		// Ecrit le login de l'auteur
		$temp.= $val["login"] . " : ";
		// Ecrit le titre ou le début du message
		if($val["reponse"]==$val["ID"]) 
			echo "<dt class=msg>".$temp.emoticon_replace(htmlentities($val["titre"])) . "</A></dt>";
		else
			echo "<dd class=msg>"
				.$temp.emoticon_replace(htmlentities(crunch($val["message"],70)))."</dd>";
	}
	echo "</td></dl>";


Bon d'accord j'ai récupéré ce code Smiley confused , mais j'aimerai connaitre l'erreur qui s'y trouve pour la corriger.
Merci d'avance Smiley biggrin
Modifié par Boubou57 (11 Mar 2009 - 15:25)
Salut,

donc plusieurs améliorations à te proposer.

Au regard de ton message d'erreur il y a de forte chance qu'il y ait une erreur de syntaxe dans ta requette !

Pour le savoir, prends systématiquement l'habitude de mettre un or die(mysql_error()); après ton mysql_query();

=> $q_sel=mysql_query('SELECT * FROM tbl_test') or die(mysql_error()); //comme ca tu peux voir l'erreur

par ailleurs avant de faire un fetch_array (d'ailleurs, tu vas voir qu'il faut plutot utiliser la fonction
fetch_assoc();)
prends l'habitude de stocker le nombre de rangs renvoyé par ta requette grace à un mysql_num_rows (ce qui t'évitera d'incrémenter inutilement une variable $i dans ta boucle)

En ce qui concerne le mysql_fetch_assoc(); pourquoi est-il préférable au mysql_fetch_array() ??

Car si tu lis la doc tu verras que par défaut la fonction fetch_array() avec son deuxième paramètre mysql_both
te renvoie en plus de l'index alphabétique un index numérique ce qui est rarement utile

=> http://fr2.php.net/manual/fr/function.mysql-fetch-array.php

Extrait

"
En utilisant MYSQL_BOTH (défaut), vous récupérerez un tableau contenant des indices associatifs et numériques.
En utilisant MYSQL_ASSOC, vous ne récupérerez que les indices associatifs
(comme le fonctionnement de la fonction mysql_fetch_assoc())..."

Pour résumer je te conseille de formater ton code de cette manière ::


<?php

$s_sel_all='SELECT * FROM tbl_x';

$q_sel_all=mysql_query($s_sel_all) or die(mysql_error());

$i_num_rows=mysql_num_rows($q_sel_all);

if($i_num_rows > 0)
{
	while($a_fields_tbl=mysql_fetch_assoc($q_sel_all)):
	
		foreach($a_fields_tbl as $s_key => $s_value):
		
			/*
			 TON PATé
			*/
		
		endforeach;
	
	endwhile;

}else{ //ce que tu veux }

?>
Merci de vos rapide de vos rapides réponses,mais je ne pige pas tout, dixit le profil Smiley confused

J'ai fait un echo de $Sql... voici le résultat:

a écrit :
SELECT forum_messages.ID,reponse,forum_messages.quand,login,email,titre,message,ismodo,IDuser,pied FROM forum_messages LEFT JOIN forum_users ON forum_messages.IDuser=forum_users.ID WHERE IDtopic=3 ORDER BY dernier DESC,ID LIMIT -20,20


Sinon pour la réponse de pouetpouet, la partie ci-dessous...

a écrit :
/*
TON PATé
*/

... de ta réponse concerne-t-il tout ce qui se trouve dans la boucle while ?
a+
Salut,

Si tes champs sont bons, l'erreur devrait se trouver ici :
a écrit :
LIMIT -20,20

L'offset doit être positif ou nul : LIMIT 0,20, LIMIT 20,20, ...

Boubou57 a écrit :
la partie ci-dessous...
/*
TON PATé
*/

... de ta réponse concerne-t-il tout ce qui se trouve dans la boucle while ?

Oui (au nom des variables près), mais il faudra enlever la boucle foreach qui n'a pas d'utilité ici.
Tu peux également profiter du test sur mysql_num_rows pour mettre en place ta structure HTML (ici le tableau) :

$i_num_rows = mysql_num_rows($q_sel_all);
if($i_num_rows > 0) {
    echo '<table>';
    while ($a_fields_tbl=mysql_fetch_assoc($q_sel_all)) {
        echo '<tr><td>...</td></tr>';
    }
    echo '</table>';
}

Ainsi, tu es sûr que l'élément table ne sera pas vide. Si la requête ne retourne rien, tu peux toujours placer un autre élément pour le message d'erreur, dans la partie else :
if($i_num_rows > 0) {
    ...
} else {
    echo '<p class="error">Pas de messages</p>';
}


a écrit :
echo "<dl><td class=msg>";
a écrit :
echo "</td></dl></tr><tr><dl><td class=msg>";

Il y a des choses à revoir dans ta structure HTML, dl ne peut contenir que dt ou dd, tandis que td ne peut se trouver que dans tr et tr dans table ou une section de table (thead, tffot ou tbody). Pour un forum, table/tr/td feront très bien l'affaire, oublie donc dl/dt/dd Smiley cligne


a écrit :
or die(...)

Ouiiin Smiley bawling
Vous me donneriez presque envie de proposer un article à ce sujet, je bondis à chaque fois que je vois ça. Non pas que ça ne soit pas utile, mais ça donne de mauvaises habitudes aux débutants qui le prennent pour argent comptant.
Pas bien :
$q = mysql_query($sql) or die(mysql_error());

Bien :
$q = @mysql_query($sql);
if (!$q)
{
    // traitement de l'erreur
}
else
{
    // requête ok, on poursuit le traitement
}
Bien entendu, le or die(mysql_error()) était sous-entendu à être utilisé en phase de test !!!
Car effectivement, pour donner ne serait-ce qu'un simple exemple, si on veut gérer la possibilité de doublons sur un champ unique, il faut gérer soi-même l'erreur !
Oui mais il sous-entend également qu'en phase d'exploit, on ne fait pas de tests Smiley eek
Autant faire des tests propres d'entrée de jeu, ça ne demande pas plus de temps que d'écrire un or die, et surtout aucune modification lors de la mise en exploitation (au pire un paramétrage pour passer en non-verbose).
Dès que je trouve le temps, je l'écris et le propose, cet article...
jeje a écrit :
Vous me donneriez presque envie de proposer un article à ce sujet, je bondis à chaque fois que je vois ça. Non pas que ça ne soit pas utile, mais ça donne de mauvaises habitudes aux débutants qui le prennent pour argent comptant.


Bien, ça m'intéresse Smiley smile . (juste que je ne vois pas quoi faire, à part un die(), lorsque la connection à mysql est impossible)
En attendant ton article, si elle avait fait un fameux or die(mysql_error()); ,
la personne ne serait pas venu poster ici...
(la personne aurait trouvé d'elle-même "si je puis dire" l'erreur)

Rien d'autre à ajouter