Réalisation d'un livre d'or avec PDO et MVC

Rechercher

Réalisation d'un livre d'or avec PDO et MVC

Par bmarjo  -  23 reponses  -  Le 23/11/2014 23:18  -  Editer  - 

Bonjour,

Je n'arrive pas à laisser un message sur la page alors je passe par le forum. J'ai fait le tuto si dessous:
http://www.apprendre-php.com/tutoriels/tutoriel-33-ralisation-d-un-livre-d-or-avec-pdo-et-mvc.html

C'est un super script qui marche très bien en local sur WAMP, mais j'ai eu la malheureuse idée de ne pas vérifier si il marchait sur l’hébergeur gratuit free, et hélas, free ne supporte pas certaine fonctionnalité du PDO...
J'ai essayé de ré encoder le tout en mysql mais je me retrouve bloquée avec 2 erreurs que je n'arrive pas à résoudre.

Sur ma page principale du livre d'or j'ai à la place de la pagination:

Warning: Division by zero in /mnt/154/sda/4/4/lerefugedubonhomme/new/livredor/guestbook-model.inc.php on line 64

et une fois le formulaire renseigné, j'ai:

Warning: Cannot modify header information - headers already sent by (output started at /mnt/154/sda/4/4/lerefugedubonhomme/new/livredor.php:9) in /mnt/154/sda/4/4/lerefugedubonhomme/new/livredor/guestbook-controller.inc.php on line 123

J'avoue ne pas être experte en Mysql et je pense avoir fais des erreurs dans le réencodage,

Auriez-vous une idée?

Merci d'avance, j’espère que vous pourrez m'aider, sinon je pense que je vais rechercher un autre script et recommencer depuis le début...

 

Réponses apportées à cette discussion

Par Cyrano  -  Le 24/11/2014 08:42  -  Haut de page  - 

Salut,
il va falloir que j'aille jeter un coup d'oeil à ce tuto un de ces jours..

Ceci étant, ça reste un tuto, ce n'est pas un script prêt à l'emploi, et l'utiliser comme tel restera toujours une mauvaise idée.
Ce qui me surprend davantage, ce sont les erreurs affichées sur free.fr que tu n'aurais pas eu en local. Mais sans voir le ode correspondant, difficile de détecter quelque erreur que ce soit.
Pourtant, la première erreur ne devrait pas être difficile à corriger : tu as une division par zéro ligne 64, il te faut donc déterminer quelle variable dans cette ligne vaut zéro... et pourquoi.

La seconde erreur découle de la première, si tu corriges la première, la seconde disparaitra.

 
Par bmarjo  -  Le 24/11/2014 10:56  -  Haut de page  - 

Oui en effet, cette variable me pose problème et je ne sais pas d'ou ça vient.
Je crois qu'une des erreurs viendrait peut etre de cette fonction en pdo:

    //debut  
     if (0 === sizeof($aListeErreurs))  
      {  
        try  
        {  
          // Création d'une requête préparée  
          $oPDOStatement = $oPDO->prepare(  
              'INSERT INTO '. DB_GUESTBOOK_TABLE .' (pseudo, pays, message, email, creation) VALUES(:pseudo, :pays, :message, :email, NOW())'  
          );  

          // Ajout de chaque paramètre à la requête  
          // Les paramètres sont automatiquement protégés par l'objet PDO  
          $oPDOStatement->bindParam(':pseudo', $_POST['pseudo'], PDO::PARAM_STR);  
          $oPDOStatement->bindParam(':pays', $_POST['pays'], PDO::PARAM_STR);  
          $oPDOStatement->bindParam(':message', $_POST['message'], PDO::PARAM_STR);  
          $oPDOStatement->bindParam(':email', $_POST['email'], PDO::PARAM_INT);  

          // Execution de la requête préparée  
          $oPDOStatement->execute();  

          // Redirection vers la même page pour vider le cache des données envoyées  
          header('Location: '. URL_GUESTBOOK);  
          exit;  
        }  
        catch (PDOException $oPdoException)  
        {  
          $aListeErreurs[] = 'Une erreur est survenue et a empêché l\'enregistrement de votre message';  
        }  
      }  

que j'ai traduit en mysql comme ceci:

    //debut  
    if (0 === sizeof($aListeErreurs))  
      {  

            // on prepare notre requête d'insertion des données  
            $pseudo = mysql_escape_string($_POST['pseudo']);  
            $pays = mysql_escape_string($_POST['pays']);  
            $message = mysql_escape_string($_POST['message']);  
            $email = mysql_escape_string($_POST['email']);  

    $sql = "INSERT INTO $DB_GUESTBOOK_TABLE VALUES('', '$pseudo', '$pays', '$message', '$email', NOW())";  

    // on lance la requête  
    $oPDOStatement = mysql_query($sql);  

        if ($oPDOStatement) {  
        // Redirection vers la même page pour vider le cache des données envoyées  
          header('Location: '. URL_GUESTBOOK);  
          exit;  
        }  
        else{  
        $message  = 'Requête invalide : ' . mysql_error() . "\n";  
        $message .= 'Requête complète : ' . $query;  
        die($message);  
        }  
      }  

Cela est il correct?
Merci

 
Par Cyrano  -  Le 24/11/2014 11:12  -  Haut de page  - 

À priori je ne vois pas d'erreur flagrante.

Ceci étant, il faudrait vérifier la version de PHP sur ton espace free.fr. Il est possible que ce soit PHP4.4.3. DOnc effectivement, PDO n'est pas actif.

Pour utiliser PHP5 chez free.fr, il faudrait que les fichiers aient une extension « .php5 » : pas pratique c'est vrai, mais dans un cas pareil, c'est la seule solution. Un détail toutefois, vérifier avec un phpinfo() si pdo_mysql est activée, il est possible que la seule qui le soit soit pdo_sqlite, ce qui ne t'avancera guère.

Pour en revenir au problème de base, je ne vois pas dans ton code la ligne correspondant à cette indiquée dans le message d'erreur : sans cet élément, difficile pour moi de te donner des indications utiles.

 
Par bmarjo  -  Le 24/11/2014 11:21  -  Haut de page  - 

ok,
Oui, j'ai tout fais pour essayer de faire passer free en version sup, avec un .htacess aussi, mais tu as raison, les deux seules activées sont sqlite et sqlite2 de mémoire... et certaines fonctionnalités PDO ne marchent pas, du coup bloquée .

comment est ce que je peux t'envoyer mon code, car ce n'est en effet pas pratique sur le forum...

 
Par Cyrano  -  Le 24/11/2014 11:24  -  Haut de page  - 

Je n'ai nul besoin de l'intégralité du code : le message d'erreur indique le fichier et la ligne : en mettant ici les quelques lignes avant et quelques lignes après, il devrait y en avoir assez pour définir les endroits à revoir. Si c'est dans une fonction, alors le code de la fonction suffira probablement.
Si ça indiquait par exemple la ligne 100, le code des lignes 90 à 105 suffiraient comme point de départ.

 
Par bmarjo  -  Le 24/11/2014 11:33  -  Haut de page  - 

ok, merci de m'accorder du temps,

alors dejà, cette fonction qui est en tout debut de page ,en pdo:

    function PDOConnect($sDbDsn, $sDbLogin, $sDbPassword)   
    {  
      try  
      {  
        $oPDO = new PDO($sDbDsn, $sDbLogin, $sDbPassword);  
      }  
      catch (PDOException $e)  
      {  
        die('Une erreur interne est survenue : impossible de se connecter à la base de données');  
      }  

      $oPDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  

      return $oPDO;  
    }  

devient en mysql:

    function PDOConnect($sDbDsn, $sDbLogin, $sDbPassword)   
    {  
         mysql_connect ($sDbDsn,$sDbLogin,$sDbPassword) or die('Une erreur interne est survenue : impossible de se connecter à la base de données');  
        $oPDO = mysql_select_db($DB_NOM);  
       return $oPDO;  
    }  

ensuite, la fonction où la variable "$nb_results_p_page" n'est plus definie (erreur signifiant division par zero, la ligne correspondante a l'erreur est le premier calcul: nombre total de page),
C est exactement la même fonction dans les 2 versions:

    function paginer($nb_results, $nb_results_p_page, $numero_page_courante, $nb_avant, $nb_apres, $premiere, $derniere)  
    {  
        // Initialisation de la variable a retourner    
        $resultat = '';  

        // nombre total de pages    
        $nb_pages = ceil($nb_results / $nb_results_p_page);  
        // nombre de pages avant    
        $avant = $numero_page_courante > ($nb_avant + 1) ? $nb_avant : $numero_page_courante - 1;  
        // nombre de pages apres    
        $apres = $numero_page_courante <= $nb_pages - $nb_apres ? $nb_apres : $nb_pages - $numero_page_courante;  

        // premiere page    
        if($premiere && $numero_page_courante - $avant > 1)  
        {  
            $resultat .= '<a href="' . htmlspecialchars($_SERVER['PHP_SELF']) . '?numeroPage=1" title="Première page">&laquo;&laquo;</a>&nbsp;';  
        }  

        // page precedente    
        if($numero_page_courante > 1)  
        {  
            $resultat .= '<a href="' . htmlspecialchars($_SERVER['PHP_SELF']) . '?numeroPage=' . ($numero_page_courante - 1) . '" title="Page précédente ' . ($numero_page_courante - 1) . '">&laquo;</a>&nbsp;';  
        }  

        // affichage des numeros de page    
        for($i = $numero_page_courante - $avant; $i <= $numero_page_courante + $apres; $i++)  
        {  
            // page courante    
            if($i == $numero_page_courante)  
            {  
                $resultat .= '&nbsp;[<strong>' . $i . '</strong>]&nbsp;';  
            }  
            else  
            {  
                $resultat .= '&nbsp;[<a href="' . htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES) . '?numeroPage=' . $i . '" title="Consulter la page ' . $i . '">' . $i . '</a>]&nbsp;';  
            }  
        }  

        // page suivante    
        if($numero_page_courante < $nb_pages)  
        {  
            $resultat .= '<a href="' . htmlspecialchars($_SERVER['PHP_SELF']) . '?numeroPage=' . ($numero_page_courante + 1) . '" title="Consulter la page ' . ($numero_page_courante + 1) . ' !">&raquo;</a>&nbsp;';  
        }  

        // derniere page         
        if($derniere && ($numero_page_courante + $apres) < $nb_pages)  
        {  
            $resultat .= '<a href="' . htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES) . '?numeroPage=' . $nb_pages . '" title="Dernière page">&raquo;&raquo;</a>&nbsp;';  
        }  

        // On retourne le resultat    
        return $resultat;  
    }
 
Par Cyrano  -  Le 24/11/2014 11:36  -  Haut de page  - 

Je ne vois là aucune division par zéro... ça va être long pour déboguer ça.

 
Par bmarjo  -  Le 24/11/2014 11:37  -  Haut de page  - 

et oui...

 
Par bmarjo  -  Le 24/11/2014 11:39  -  Haut de page  - 

est ce que la première fonction a l'air exacte? j'ai un gros doute ...

 
Par Cyrano  -  Le 24/11/2014 11:43  -  Haut de page  - 

J'ai édité des deux message avec le code pour les fusionner. Je regarde ça, il me faut un petit moment

 
Par Cyrano  -  Le 24/11/2014 11:49  -  Haut de page  - 

Ok, il faut que tu remontes jusqu'à l'appel de ta fonction paginer pour vérifier le paramètre envoyé, d'où il sort et/ou comment est défini le nombre.

À priori, il devrait avoir une valeur par défaut précisément pour éviter ce genre de problème. Tu peux aussi ajouter un test au tout début de ta fonction, par exemple :

    if(is_null($nb_results_p_page) || $nb_results_p_page == 0)
    {
        throw new Exception ("Le nombre de résultats par page doit être supérieur à zéro");
    }

Dans ce cas, si la valeur vaut NULL ou 0, ça va planter immédiatement, il faudra donc corriger ça avant de le mettre en ligne.

 
Par bmarjo  -  Le 24/11/2014 11:57  -  Haut de page  - 

ok, je regarde ça tout de suite merci

 
Par bmarjo  -  Le 24/11/2014 12:02  -  Haut de page  - 

Fatal error: Uncaught exception 'Exception' with message 'Le nombre de résultats par page doit être supérieur à zéro' in /mnt/154/sda/4/4/lerefugedubonhomme/new/livredor/guestbook-model.inc.php:66 Stack trace: #0 /mnt/154/sda/4/4/lerefugedubonhomme/new/livredor/guestbook-view.inc.php(34): paginer(20, 'MAX_MESSAGES_PA...', 1, 4, 4, 1, 1) #1 /mnt/154/sda/4/4/lerefugedubonhomme/new/livredor.php(106): require('/mnt/154/sda/4/...') #2 {main} thrown in /mnt/154/sda/4/4/lerefugedubonhomme/new/livredor/guestbook-model.inc.php on line 66

sur ma page principale en mettant le test au debut de la fonction

 
Par bmarjo  -  Le 24/11/2014 12:05  -  Haut de page  - 

si c'est trop compliqué, je crois que je vais tout refaire et repartir d'un autre code déjà mysql...

 
Par Cyrano  -  Le 24/11/2014 12:08  -  Haut de page  - 

Normal, mais maintenant, il faut remonter dans la chronologie de l'exécution du code : où est appelée ta fonction paginer() ?

Regarde la StackTrace du message d'erreur :

    Fatal error:  
        Uncaught exception 'Exception'  
        with message 'Le nombre de résultats par page doit être supérieur à zéro'  
            in /mnt/154/sda/4/4/lerefugedubonhomme/new/livredor/guestbook-model.inc.php:66  
        Stack trace:  
            #0 /mnt/154/sda/4/4/lerefugedubonhomme/new/livredor/guestbook-view.inc.php(34): paginer(20, 'MAX_MESSAGES_PA...', 1, 4, 4, 1, 1)  
            #1 /mnt/154/sda/4/4/lerefugedubonhomme/new/livredor.php(106): require('/mnt/154/sda/4/...')  
            #2 {main} thrown in /mnt/154/sda/4/4/lerefugedubonhomme/new/livredor/guestbook-model.inc.php on line 66  

Tu peux voir que l'appel est fait dans guestbook-view.inc.php à la ligne 34. Or l'appel envoit en second paramètre une constante MAX_MESSAGES_PA... : n'as-tu pas oublié de faire un include dans ce fichier d'un autre fichier de configuration où sont définies tes constantes ?

 
Par bmarjo  -  Le 24/11/2014 12:19  -  Haut de page  - 

Voici ce que j'ai dans ma page principale :livredor.php

<?php

/**
* Programme principal
* Construit la page à partir de tous les fichiers
*/
require(dirname(FILE).'/livredor/guestbook-config.inc.php');
require(dirname(FILE).'/livredor/guestbook-model.inc.php');
require(dirname(FILE).'/livredor/guestbook-controller.inc.php');
require(dirname(FILE).'/livredor/guestbook-view.inc.php');
?>

Pour l'appel des pages, la constante MAX_MESSAGE_PAR_PAGE est definie dans
guestbook-config.inc.php

cela n'est pas suffisant?
je n'ai aucun include nulle part, mais MAX_MESSAGE_PAR_PAGE est bien definie dans guestbook-view.inc.php puisqu'il m'affiche 5 messages par page

 
Par Cyrano  -  Le 24/11/2014 12:31  -  Haut de page  - 

C'est dans ton fichier guestbook-view.inc.php que tu dois ajouter un include de ce fichier guestbook-config.inc.ph. Sans nécessairement changer le reste.

Teste ça, tu devrais voir un notable changement.

 
Par bmarjo  -  Le 24/11/2014 12:49  -  Haut de page  - 

j'ai rajouté cette ligne dans guestbook-view.inc.php mais toujours même message d'erreur

<?php include("/livredor/guestbook-config.inc.php"); ?>

 
Par Cyrano  -  Le 24/11/2014 14:20  -  Haut de page  - 

Essaye d'avancer avec un petit minimum de logique.

Là, il y a probablement un soucis avec le chemin que tu as indiqué dans ton include. Juste par curiosité, sais-tu quelle différence il existe entre :
- "/chemin/vers/fichier"
- "./chemin/vers/fichier"
Formulé autrement, à quoi sert l'utilisation du point en début de chemin ?

 
Par bmarjo  -  Le 24/11/2014 14:26  -  Haut de page  - 

il me semble que le / par du fichier ou il est actuellement, contrairement au ../ qui remonte au dossier parent, par contre le ./, il me semblait que c'etait également comme le /

 
Par Cyrano  -  Le 24/11/2014 14:31  -  Haut de page  - 

Ok, donc on va corriger :

  1. ../ remonte d'un niveau dans l'arborescence par rapport au fichier lui-même;
  2. ./ indique le répertoire courant par rapport au fichier luii-même;
  3. / indique la racine du serveur

Les deux premiers sont des chemins relatifs, entendre par là « relatifs au fichier » où se trouve l'instruction; le troisième est un chemin absolu par rapport à la machine, et / est la racine de la machine et non du serveur web. Sur un serveur de production, comme celui de free.fr, l'erreur ne s'affiche pas, mais je suis pratiquement certain que ton include ne foncitonne pas et que le fichier n'est pas trouvé parce que tu as utilisé la troisième option, donc le fichier n'est pas recherché par rapport au fichier appelant mais par rapport à la racine de la machine.

Effectue le correctif, et teste à nouveau.

 
Par bmarjo  -  Le 24/11/2014 14:50  -  Haut de page  - 

ok merci pour l'explication,

en effectuant le correctif, il ne me change rien, par contre, si je lui met autre chose qui est faux, là il me met des vrais messages d'erreurs indiquant qu'il ne trouve pas le chemin :

Warning: include() [function.include]: Unable to access ../livredor/guestbook-config.inc.php in /mnt/154/sda/4/4/lerefugedubonhomme/new/livredor/guestbook-view.inc.php on line 11

Warning: include(../livredor/guestbook-config.inc.php) [function.include]: failed to open stream: No such file or directory in /mnt/154/sda/4/4/lerefugedubonhomme/new/livredor/guestbook-view.inc.php on line 11

Warning: include() [function.include]: Failed opening '../livredor/guestbook-config.inc.php' for inclusion (include_path='/mnt/154/sda/4/4/lerefugedubonhomme/include:.:/usr/php5/lib/php') in /mnt/154/sda/4/4/lerefugedubonhomme/new/livredor/guestbook-view.inc.php on line 11

je crois que je n'arrive plus du tout à refléchir,
merci de ton aide,
je pense que je vais laisser tomber cette partie du code pour l'instant et avancer tranquillement sur la suite...

 
Par Cyrano  -  Le 24/11/2014 17:09  -  Haut de page  - 

Et pourtant, ça devrait être la simplicité même :

Tu n'as pas 36 solutions, soit un chemin relatif, soit un chemin absolu.

  1. Pour le chemin relatif, ça commencera par « ./ » (un seul point);
  2. Pour un chemin absolu, ça commencera donc par « / » (donc sans point) mais qu'il faudra construire à partir du chemin absolu du répertoire courant. Pour faire ça, tu récupères d'abord le chemin absolu du répertoire courant :

    $repertoire_racine = realpath(dirname(dirname(__FILE__))); // À noter qu'en PHP5, tu pourrais utiliser realpath(dirname(__DIR__)) au lieu de doubler l'emploi de dirname pour remonter d'un niveau supplémentaire;  
    $cheminConfig = $repertoire ."rep_config/fichier.conf.php";  
    

Et pour vérifier, tu ajoutes quelque chose du genre :

    var_dump($cheminconfig);  

Histoire de vérifier que ce chemin a du sens.

 

Ajouter une réponse à la discussion

Seuls les membres connectés sont autorisés à poster dans les forums !

Identifiez-vous
Join |  ID/MDP? |