IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Réfactorisation en MVC


Sujet :

Langage PHP

  1. #1
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut Réfactorisation en MVC
    Bonjour

    (Je ne sais pas si je suis sur le bon sous-forum ou pas donc désolé d'avance si je me suis trompé)

    Voila, je commence la réfactorisation en MVC de mon script d'espace membre communautaire et je souhaite avoir vos avis sur mes débuts en MVC car c'est la première fois que j'utilise le MVC. J'ai bien-sur déjà lu le cours MVC et d'autres cours sur le net.

    Mais je voulais avoir vos avis également. Est-ce sécurisé ? etc

    Je poste uniquement le MVC d'une page seulement car sinon trop long.. voici le MVC de la page send.php qui sert à deux choses : envoyer un message a un autre membre et afficher la conversation. J'attends vos suggestions

    Model :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <?php
     
    // Renvoie les informations sur un membre
    function getProfile($idmbr) {
        global $pdo;
        $profile = $pdo->prepare('SELECT id, nom, prenom, confirmed_at FROM users WHERE id = ? AND confirmed_at IS NOT NULL');
        $profile->execute(array($idmbr));
        if ($profile->rowCount() == 1)
            return $profile->fetch();  // Accès à la première ligne de résultat
        else
            $_SESSION['flash']['danger'] = "Aucun membre ne correspond à l'identifiant '$idmbr'";
            header('Location: index.php?p=inbox');
        exit();
    }
     
    // Renvoie les messages de la conversation
    function getMessages($idmbr, $user_id) {
        global $pdo;
        $messages = $pdo->prepare('SELECT id, id_expediteur, id_destinataire, message, date_envoi, date_lecture FROM messages WHERE (id_destinataire = '.$user_id.' AND id_expediteur = ?) OR (id_destinataire = ? AND id_expediteur = '.$user_id.') ORDER BY date_envoi DESC LIMIT 0, 20');
        $messages->execute(array($idmbr, $idmbr));
        return $messages;
    }
     
    // Remplace null par une date de lecture en cas de messages non lus.
    function getRead($idmbr, $user_id) {
        global $pdo;
        $pdo->prepare('UPDATE messages SET date_lecture = NOW() WHERE id_expediteur = ? AND id_destinataire = ? AND date_lecture IS NULL')->execute([$idmbr, $user_id]);
    }
    View :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    <div class="page-header">
        <h2>Ecrire à <?php echo htmlspecialchars($profile->prenom); ?> <?php echo htmlspecialchars($profile->nom{0}); ?></h2>
    </div>
     
    <form action="" method="post">
        <textarea name="message" id="inputHelpBlock" class="form-control" rows="3"></textarea>
        <button type="submit" class="btn btn-primary btn-lg btn-block">Envoyer</button>
    </form>
     
    <h2>Historique</h2>
     
    <?php
     
    // Boucle pour l'affichage de la conversation
    while ($donnees = $messages->fetch())
    {
        switch ($donnees->id_expediteur)
        {
            case $user_id : $couleur_fond = "info"; break;
            case $idmbr : $couleur_fond = "warning"; break;
        }
        switch ($donnees->date_lecture)
        {
            case null : $lecture_msg = "non lu"; break;
            case !null : $lecture_msg = 'lu '.period($donnees->date_lecture).''; break;
        }
        ?>
     
        <div style="padding: 5px;" class="row bg-<?php echo "$couleur_fond" ?>">
            <div class="col-xs-6"><p class="text-left"><small>envoyé <?php echo period($donnees->date_envoi); ?></small></p></div>
            <div class="col-xs-6"><p class="text-right"><small><?php echo "$lecture_msg" ?></small></p></div>
            <div class="col-xs-12"><p class="text-left"><?php echo nl2br(htmlspecialchars($donnees->message)); ?></p></div>
        </div>
     
        <br>
     
    <?php } ?>
    Controller :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    <?php
    logged_only(); // contrôle si le membre est connecté.
     
    $titre = 'Envoyer un message'; // Titre de la page pour la balise meta title.
     
    $idmbr = (int) $_GET['idmbr']; // Sécurise la variable idmbr passée par l'url.
     
    $user_id = $_SESSION['auth']->id; // Récupère l'id du membre connecté.
     
    require 'model/send.php'; // le model...
     
    $profile = getProfile($idmbr); // Récupère les informations du membre.
     
    getRead($idmbr, $user_id); // Update la date de lecture en cas de messages non lus.
     
    // On sécurise le message avant de l'enregistrer dans la table messages.
    if(!empty($_POST)){
    	if(empty($_POST['message'])){
    		$_SESSION['flash']['danger'] = "Vous devez écrire un message";
    	} else {
    		$message = trim(htmlspecialchars(stripslashes($_POST['message'])));
    		$req = $pdo->prepare('INSERT INTO messages (id_expediteur, id_destinataire, message, date_envoi) VALUES('.$user_id.', '.$idmbr.', ?, NOW())');
    		$req->execute(array($message));
    		$_SESSION['flash']['success'] = 'Message envoyé !';
    	}
    }
     
    // Affiche la conversation.
    $messages = getMessages($idmbr, $user_id);
     
    // La vue...
    require 'view/send.php';
    J'attends avec impatience vos suggestions et surtout savoir si pour le moment j'ai bien bossé
    (Je ne souhaite pas passer a la POO, encore trop tôt pour moi..)

  2. #2
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Salut,

    c'est pas mal du tout

    ce qui me pose problème c'est la redirection dans le modèle, le modèle doit renvoyer le résultat du traitement mais ne peut être chargé de rediriger le client.

    Dans le modèle, tu peux aussi t'assurer que $idmbr est strictement positif avant de lancer le traitement lourd avec PDO.

    Après pour faciliter la lecture, j'opterai pour la notation courte : <?= au lieu de <?php echo, ensuite je créerai un closure de ce genre pour gérer l'échappement à l'affichage : $hsc = function($p) { return htmlspecialchars($p, ENT_QUOTES, 'utf-8'); }; ce qui te permettrait d'avoir à la place de <?php echo htmlspecialchars($profile->prenom); ?>, <?= $hsc($profile->prenom) ?>

  3. #3
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    Je suis en train de faire les modifs la.

    par contre j'ai du mal à trouver la solution pour la redirection dans le model. J'ai besoin de savoir si le membre existe vraiment.. donc je ne sais pas comment faire la vérif autrement.. une idée ?

    Merci pour ton code (fonction) sur le htmlspecialchars.. très utile pour raccourcir le code !

  4. #4
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    quand je dis
    Citation Envoyé par rawsrc Voir le message
    le modèle doit renvoyer le résultat du traitement mais ne peut être chargé de rediriger le client.
    cela veut juste dire que la fonction peut très bien renvoyer un simple false pour indiquer le chargement du profile n'a rien donné. false intercepté par le contrôleur qui dans ce cas de figure se charge de la redirection, tu vois ?

    D'ailleurs, je vais te mettre le doigt sur autre chose de pas très logique bien que fonctionnel : si le chargement du profile ne donne rien, tu te sers de quand même de $_SESSION pour ton traitement. D'emblée, on pourrait penser : profil ok => session. Ton système est fonctionnel voire à la rigueur acceptable mais c'est juste pour te donner du grain à moudre

  5. #5
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    Citation Envoyé par rawsrc Voir le message
    D'ailleurs, je vais te mettre le doigt sur autre chose de pas très logique bien que fonctionnel : si le chargement du profile ne donne rien, tu te sers de quand même de $_SESSION pour ton traitement. D'emblée, on pourrait penser : profil ok => session. Ton système est fonctionnel voire à la rigueur acceptable mais c'est juste pour te donner du grain à moudre
    la, par contre je n'ai rien compris

    Essaie de me réexpliquer stp

  6. #6
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Il est étrange de faire appel à une session quand le profil n'a pas pu être chargé...

  7. #7
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    voici la modif pour la redirection..

    la fonction avec FALSE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // Renvoie les informations d'un membre
    function getProfile($idmbr) {
        global $pdo;
        $profile = $pdo->prepare('SELECT id, nom, prenom, confirmed_at FROM users WHERE id = ? AND confirmed_at IS NOT NULL');
        $profile->execute(array($idmbr));
        if ($profile->rowCount() == 1)
            return $profile->fetch();  // Accès à la première ligne de résultat
        else
            return false;
    }
    et dans le Controleur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $profile = getProfile($idmbr); // Récupère les informations du profil.
    if ($profile === false) {
    	$_SESSION['flash']['danger'] = "Aucun membre ne correspond à l'identifiant '$idmbr'";
    	header('Location: index.php?p=inbox');
    	exit();
    }
    comme ça ?

  8. #8
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    ouaip, mais pourquoi utilises-tu une session pour gérer la remontée des messages d'erreur quand bien même l'extraction du profile n'a rien donné ? Pas de profile donc pas de session, non ?

  9. #9
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    non ma gestion des messages d'erreur ou de succès n'a pas de rapport avec le chargement d'un profil ou non. C'est simplement une solution que j'ai trouvé sur un site d'apprentissage php (grafikart) pour afficher un message au visiteur.

    Je met la ligne suivante ou je veux dans mon appli :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $_SESSION['flash']['danger'] = "Un exemple de message d'erreur";
    // ou la ligne..
    $_SESSION['flash']['success'] = "Un exemple de message de succès";
    et dans le fichier de template je met :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        <?php if(isset($_SESSION['flash'])): ?>
            <?php foreach($_SESSION['flash'] as $type => $message): ?>
                <div class="alert alert-<?= $type; ?> alert-dismissible" role="alert">
                    <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                    <?= $message; ?>
                </div>
            <?php endforeach; ?>
            <?php unset($_SESSION['flash']); ?>
        <?php endif; ?>
    avec cette solution je n'utilise pas de variable GET dans l'url.

  10. #10
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    houlà !! c'est quoi cette méthode ?

    t'imagine le cas où t'as effectivement une session valide pour l'utilisateur et que tu y loges dedans des messages propres au système qui du coup vont rester en session d'une page à l'autre...
    Bonjour le débogage...

    Encore un astuce moisie. Éloigne toi de cette pratique et trouve autre chose de plus propre

  11. #11
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    Le message reste seulement jusqu'à la seconde page au moment ou le message est intercepté pour l'affichage.
    de plus, la solution fonctionne très bien avec mon espace membre qui lui même utilise les sessions..
    Je trouve que c'est une solution propre, sans aucun bug et facile à utiliser.
    mais je prends note de ta remarque!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 24/02/2009, 13h06
  2. [GEF]GEF EditViewPart MVC etc...
    Par georgemel dans le forum Eclipse Platform
    Réponses: 4
    Dernier message: 19/07/2007, 20h07
  3. [MVC][JAVABEAN][JSP]
    Par phileme dans le forum Servlets/JSP
    Réponses: 8
    Dernier message: 12/07/2004, 11h22
  4. [MVC] Différences entre les framework MVC push et pull ?
    Par XavierZERO dans le forum Frameworks Web
    Réponses: 5
    Dernier message: 15/01/2004, 14h12
  5. Classe abstraite / MVC
    Par caramel dans le forum MVC
    Réponses: 5
    Dernier message: 01/04/2003, 10h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo