8721 sujets

Développement web côté serveur, CMS

Bonjour!
J'essaie d'être claire, en précisant que je ne possède pas forcément tous les termes...

Voilà, mon site contient un agenda, où les événements peuvent être affichés par leur n° d'ID (par la fonction GET).
Mais je me suis aperçue aujourd'hui que si le n° en question n'existait pas, la page s'affichait sans le CSS... et sans header.
J'ai essayé de créer une page d'erreur, ou à tout le moins un message d'erreur, mais je n'y arrive pas!!!

J'ai tenté différentes méthodes (if (!$result), die, ...), mais rien à faire!
Et je ne comprends pas d'où viennent mes erreurs!

Grosso modo, le début du code que j'essaie de modifier:
$id=$_GET["id"];	
	  $query="SELECT * FROM $table_agenda WHERE id='$id'";
	  $result=mysql_query($query);
	  while($ligne=mysql_fetch_array($result))

ensuite, bien sûr, ça détaille les résultats à afficher, et le reste de la page...
Comment faire pour "forcer" l'affichage d'un message d'erreur?

Quelqu'un a-t-il une idée?
Merci d'avance!
Modifié par bisane (12 May 2007 - 17:13)
Salut Smiley smile

Voici une solution : il faut d'abord tester l'existence de ta variable GET. Tu peux également vérifier que si elle existe elle est bien comprise entre 2 bornes. Sinon --> $id = 0 (pour que la requête ne ramène aucun résultat). La fonction $nbLignes = mysql_num_rows($result); permet de connaître le nombre d'enregistrements trouvés par une requête : si c'est égal à 0 tu affiches ton message d'erreur, sinon tu affiches l'évènement...
if (isset($_GET['id'])) {
	@$id = intval($_GET['id']);
        if ($id < 1 || $id > 999999 ) {
	$id = 0;
        }
} else 	  
	$id = 0;
}


$query="SELECT * FROM $table_agenda WHERE id='$id'";
$result=mysql_query($query);
$nbLignes = mysql_num_rows($result);
if ($nbLignes == 0) {
    // Affichage de "Aucun Evènement...
}
else
{
while($ligne=mysql_fetch_array($result)){
    // Affichage de l'Evènement...
    ...
    }
}

A+
Merci Heyoan! Super!

N'avais pas du tout eu l'idée du comptage des lignes, et ça marche sans problème...

Je me permets juste de dire que je ne suis pas arrivée à faire cela: "il faut d'abord tester l'existence de ta variable GET", que j'avais déjà fait une recherche sur le net sans succès, et qu'il me semble que ça peut servir à d'autres... et que j'imagine que ça doit être simple quand on sait comment faire!

Je laisse donc très momentanément le sujet sans le [résolu], même s'il l'est pour moi!

Bon printemps à tous!
Modifié par bisane (12 May 2007 - 09:02)
Hello Bisane !

You're welcome !

bisane a écrit :
Je me permets juste de dire que je ne suis pas arrivée à faire cela: "il faut d'abord tester l'existence de ta variable GET"
Si ! Si ! Tu as réussi à le faire : c'est le morceau de code
if (isset($_GET['id'])) {

A+ Smiley biggrin
Ben non, j'ai pas réussi!

Je ne l'ai pas mis, ce bout de code, j'ai essayé de le modifier sans succès! (juste pour vérifier que l'ID en question existe dans la table)

Je n'ai mis que la fin, après le $query et le $result...

Le problème, c'est que le site étant "interactif", il y a des utilisateurs qui publient un article, qu'ils suppriment ensuite. Mais les moteurs, eux, ont mémorisé le post et le n° d'ID... C'est donc pour éviter que les visiteurs se retrouvent devant une page du type http://monsite.com/article.php?id=id où il n'y a rien...
J'ai réussi grâce au $nbLignes, mais j'imagine que ça pourrait effectivement se faire "en amont", puisque l'id n'existe effectivement plus dans la table...

Je ne suis pas sûre d'être très claire...
Mais pour caricaturer
if (!isset($_GET['id'])) {
ne fonctionne pas...
Modifié par bisane (12 May 2007 - 09:58)
Salut,

la ligne qui pose problème ne fait que vérifier l'existence de la variable PHP $_GET['id'], elle ne vérifie pas que cette valeur correspond à quelque chose.

En fait, c'est pour éviter que ton code PHP ne soit exécuté si le visiteur n'a pas sélectionné un jour précis dans ton agenda, mais arrive par exemple sur la page où cet agenda est présenté ... Je ne suis pas sûr d'être clair Smiley smile
bisane a écrit :
juste pour vérifier que l'ID en question existe dans la table

Il y a effectivement un quiproquo : le isset ne vérifie pas que la valeur contenue dans ta variable id existe bien dans la table, il vérifie que ta variable id elle-même existe bien.

Pour être plus clair, l'affichage d'un évènement se fait par un click sur
http://circul.arts.free.fr/agenda/evenement.php?id=1958

le isset vérifie que le lien (par exemple modifié par ton visiteur...) n'est pas
http://circul.arts.free.fr/agenda/evenement.php?idazeaze=1958
car dans ce dernier cas ta variable $_GET['id'] n'existerait pas et si le reste de ton code tente de l'utiliser tu aurais un warning.

Si ce que je te dis est complètement ésotérique Smiley ravi c'est sans doute que ton hébergeur à mis la variable register_globals à On ce qui signifie que tu n'as pas besoin de déclarer tes variables avant de les utiliser . Ce qui est pourtant une bonne idée pour limiter les failles de sécurité. Pour plus d'infos voici un lien.

A+

Edit :On s'est croisés Smiley cligne
Modifié par Heyoan (12 May 2007 - 10:49)
Salut,

Si tu veux remonter en amont alors c'est au niveaux des liens qui permettent d'aller vers cette page.

Mais si tu supposes que ça proviens de moteurs de recherche qui ont mémorisé cette adresse et bien evidemment tu n'as pas la main dessus.


la seule chose qui me viens a l'esprit que tu pourrais faire.

et je precise c'est juste une idée je n'ai jamais pratiqué la chose Smiley confused .

c'est aprés avoir detecter qu'il n'y a pas l'id dans ta base de données de provoquer une redirection qui va retourner un code d'erreur 301 pour indiquer que c'est une redirection d'un lien qui a été déplacé definitivement.


header("Location:http://une_adresse_avec_message_d'erreur",true,301);



voir là pour la description de header

en général les moteurs ne vont pas continuer à référencer un tel lien. enfin normalement car ils font ce qu'ils veulent.

Pascal
Modifié par CPascal (12 May 2007 - 11:11)
Merci à vous trois (Thomas D. Heyoan, CPascal) ! - On avance, et on précise!!!

Thomas D. : c'est très clair. Ce qui n'empêche qu'il doit bien y a voir un moyen rapide, peu vorace en ressources, pour vérifier que l'ID existe bien, et sinon d'afficher une autre page...

Heyoan : rien d'ésotérique!
J'essaierai de regarder ton lien pour les failles de sécurité, mais j'avoue que je cours toujours après le temps, et que je vais au plus pressé!
En tout cas, l'url (qui pourrait être modifiée par "je-ne-sais-qui") renvoie à ma page d'erreur... Ca a l'air de ne pas trop mal fonctionner!

CPascal
Il me semble que ta solution serait assez consommatrice de ressources... pour pas grand chose!
Mais je me trompe peut-être!

Encore une fois, je fais les choses par essais et erreurs, et ne suis pas du tout une pro du PHP (bien que je l'utilise beaucoup!), mais il me semble qu'on devrait pouvoir ne lancer cette ligne
$query="SELECT * FROM $table_agenda WHERE id='$id'";
que si l'ID existe bien...

J'espère à mon tour que je suis claire, et pas trop ésotérique!!!
Re,

pour ma solution je ne sais pas pour les ressources. evidemment ça va doubler les requêtes au serveur dans le cas d'un appel erroné mais ces appels ne devraient justement pas durer si mon truc marche.

reste qu'une fois de plus je n'ai pas de retour d'expérience de la chose.


a écrit :
Bisane a dit:

il me semble qu'on devrait pouvoir ne lancer cette ligne

$query="SELECT * FROM $table_agenda WHERE id='$id'";

que si l'ID existe bien...


dans l'absolu on peut l'ecrire et la lancer même si il n'existe pas de table_agenda et l'ecrire même sans bases de données Smiley lol .

mais pour repondre ( je l'espere ) à ta question il n'y a pas d'autre moyen d'interroger une base de donnée que de l'interroger et donc d'écrire une requête et de l'executer.

donc que ce soit en aval ou en amont il faudra en passer par là. maintenant a toi de voir dans ton code où positionner ce test pour qu'il y est le moins de requetes possibles.

peut-être en amont ET en aval. et peut-etre seulement en aval çà depend un peu de comment est fais ton application. mais surement pas que en amont puisque tu crains les moteurs de recherche.

voila en esperant n'avoir pas été trop ésotérique moi non plus

pascal
Modifié par CPascal (12 May 2007 - 12:32)
il suffit de regarder la réponse de la requete:

          $id= $_GET["id"];	

	  $query="SELECT * FROM $table_agenda WHERE id='$id'";

	  $result=mysql_query($query);

	  while($ligne=mysql_fetch_array($result)) ...
 


donnerais par exemple:

      //vérifie que la variable n'est définie, si non on lui met la valeur FALSE 
      $id= ( isset($_GET["id"]) ? $_GET['id'] : FALSE;	

      if (  is_numeric($id) {
           $query="SELECT * FROM $table_agenda WHERE id='$id'";
           $result=mysql_query($query);
           if ( $ligne=mysql_fetch_array($result) ) {
               //
               //   le code pour afficher la page ..
           }
           else {
               // l'id n'existe pas
               header('Status: 404 Not Found', true, 404);
               // ou mieux si la page a éxister
               header(‘HTTP/1.0 410 Gone’, true, 410);
               // reste de la page ...
           }
      }
      else {
         echo 'l'id n'est pas un chiffre ... mauvaise syntaxe';
         header(‘HTTP/1.0 410 Bad Request’, true, 400);
         // reste de la page ...
      }


si aucun controle n'est fait sur la variable $id quelqun peut dans certain cas modifier la requete sql et acceder a des données (les détruires, récupérées ...)
pour l'économie en ressource mieux:
- vaut éviter les * pour selectionner les champs, il faudrait les nomer clairement id,titre,...
- bien choisir les types de colonnes données utiliser dans la table ( int signed/ unsigned .. vachar blob ..)
Smiley biggrin
Modifié par desg (12 May 2007 - 15:11)
Merci desg! On progresse!

J'ai mis un peu de temps à répondre, mais mon ordi a planté... et je crains que ça ne soit en partie à cause d' EasyPhp, qui n'a pas apprécié que certaines parenthèses soient restées ouvertes...
Et moi, bien sûr, j'ai redémarré, fait un scan antivirus, vérifié ma bdr...!

Bref, je corrige le code tout de suite, au cas où certains souhaiteraient l'utiliser!!!
//vérifie que la variable n'est définie, si non on lui met la valeur FALSE 
      $id= ( isset($_GET["id"])) ? $_GET['id'] : FALSE;	

      if (  is_numeric($id)) {
           $query="SELECT * FROM $table_agenda WHERE id='$id'";
           $result=mysql_query($query);
           if ( $ligne=mysql_fetch_array($result) ) {

               //   le code pour afficher la page ..

           }

           else {
               // l'id n'existe pas
               header('Status: 404 Not Found', true, 404);
               // ou mieux si la page a éxister
               header(‘HTTP/1.0 410 Gone’, true, 410);
               // reste de la page ...
           }

      }

      else {

         echo 'l'id n'est pas un chiffre ... mauvaise syntaxe';
         header(‘HTTP/1.0 410 Bad Request’, true, 400);
         // reste de la page ...

      }
J'espère que je n'en ai pas oublié! (des parenthèses...)

Ensuite, je me suis un peu perdue dans mon propre code avec les accolades, les codes html, etc... Mais ça marche impec!
(évidemment, j'aurais construit ma page différemment si je l'avais faite en fonction de ce que je demande ici, mais qaund je reprends mes codes -mon expérience augmentant, en particulier grâce à vous !- je m'aperçois à quel point je les ai mal faites!!!)
Et il me semble en effet que ce code est économe en requêtes inutiles!
Et peut-être assez protectrice d'éventuelles injections...

Et j'ai découvert (j'en fait tous les jours, des découvertes... parfois des moins bonnes!) qu'on pouvait utilement remplacer le "while($ligne=mysql_fetch_array($result))" par une condition "if ($ligne=mysql_fetch_array($result))" ... Je retiens l'idée!!!

Il me semble en tout cas que je peux maintenant marquer le sujet comme résolu... Ce qui n'empêche pas d'autres idées!!!
Merci à tous!

PS: j'édite pas pour le plaisir... je me battais avec les couleurs! Je crois que s'y suis arrivée!
Modifié par bisane (12 May 2007 - 17:13)
Bonjour,

Voila j'utilise ce code sur ma page news.php pour afficher mes news par leur ID (par exemple news.php?id=10). Je réécris mes url en injectant le titre de la news dedans ce qui me donne par exemple 10-titre_de_la_news.php.
Le soucis c'est que n'importe quel titre marche tant que l'ID est bon, 10-mauvais_titre_de_la_news.php marche tout aussi bien que le bon titre. Si j'ai à modifier le titre de la news, cela me créera donc un nouveau lien qui sera tout aussi valide que le précédent.
J'ai donc peur que cela me fasse du duplicate content chez Google puisqu'il visitera l'ancienne news indexée puis la nouvelle : 2 url, contenu identique = pas bon.

J'aimerai donc modifier ce script pour qu'il vérifie que le titre de la news dans la BDD corresponde bien à l'ID demandée.

J'ai essayé comme cela mais cela ne marche pas :
function filter($in) {
        $search = array ('@[b]@i','@[D]@i','@[F]@i','@[G]@i','@[H]@i','@[J]@i','@[K]@i','@[L]@i','@[M]@i','@[N]@i','@[P]@i','@[Q]@i','@[R]@i','@[S]@i','@[T]@i','@[V]@i','@[W]@i','@[X]@i','@[Y]@i','@[Z]@i','@[éèêëÊËE]@i','@[àâäÂÄA]@i','@[îïÎÏI]@i','@[ûùüÛÜU]@i','@[ôöÔÖO]@i','@[çC]@i','@[ ]@i','@[^a-zA-Z0-9_]@');
        $replace = array ('b','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z','e','a','i','u','o','c','_','');
        return preg_replace($search, $replace, $in);
    }
 
$newsId= ( isset($_GET["id"])) ? $_GET['id'] : FALSE;
$titre= ( isset($_GET["titre"])) ? $_GET['titre'] : FALSE;
    if (  is_numeric($newsId) && is_string(filter($titre)) ) {
    $sql = 'SELECT * FROM news WHERE newsId = ' . $newsId . ' AND titre =  ' . $titre;   
    $rc = mysql_query($sql);
    if ( $data = mysql_fetch_assoc($rc) ) {
   //afficher la news
   }else
    {
   //mauvaise id de news
   }
    }else
    {
   //ce n'est pas une id valide
   }


Merci à vous Smiley smile

(Je sais que je remonte un vieux sujet mais c'est ce système que j'utilise sur mon site)[/b]
Modifié par Guillaume80 (11 May 2008 - 19:07)