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

PHP & Base de données Discussion :

MVC & besoin d'appeler une fonction dans la vue (générer URL)


Sujet :

PHP & Base de données

  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2019
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2019
    Messages : 67
    Par défaut MVC & besoin d'appeler une fonction dans la vue (générer URL)
    Bonjour à tous,

    Je sollicite votre aide concernant un problème que je rencontre, sur mon application MVC.

    J'ai implémenté récemment des composants issus de Symfony pour me simplifier la tâche, notamment le routing et les annotations Doctrine.

    Cela me permet de gérer les routes plus simplement grâce aux annotations comme dans Symfony, exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /**
         * @Route({"/home", "/"}, name="home")
         */
        public function home($ajax = false)
        {
            $nb_infos = $this->InfoTable->count();
            $nb_utilisateurs = $this->UserTable->count();
     
            $this->render("VueIndex", compact('nb_infos', 'nb_utilisateurs'));
        }
    Jusqu'ici aucun soucis, en accédant à l'url http://url.com/home, c'est la bonne action qui est appelée et la page s'affiche.

    Cependant j'aurai aimé profiter aussi de la génération d'URL de manière dynamique, pour arrêter d'écrire des liens manuellement dans mes vues, en remplaçant :
    <a href="/home">lien</a> par (exemple) <a href="<?= path('home'); ?>">lien</a>.

    Malheureusement si je créé une fonction "path" dans une de mes classes, la vue est incapable de l'appeler et je me retrouve avec une erreur du type :
    Fatal error: Uncaught Error: Call to undefined function path()
    Et je sais aussi qu'une Vue n'est pas censée appeler un controleur ou un service... (twig le gère très bien dans symfony et on ne s'en soucie pas mais là c'est différent).
    C'est pourquoi toute remarque est la bienvenue, j'aimerai respecter au mieux les bonnes pratiques. Je sais que ma question est un peu vague donc n'hésitez si vous avez des suggestions

    Merci d'avance !

    Voici en bonus la méthode qui me permet d'afficher une Vue (qui se trouve dans mon fichier AppController.php) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    protected function render($view, $variables = [])
        {
            extract($variables);
     
            require($_ENV['APP_DIR'] . "/Vues/" . $view . ".php");
        }

  2. #2
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2018
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Thaïlande

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2018
    Messages : 119
    Par défaut
    Bonjour,

    En model MVC, la vue n'appelle pas de fonction se trouvant dans le controller (ni ailleurs), elle ne fait que rendre ce que le controller lui envoie.

    Logiquement pour generer des url dynamiquement, il faudrait le faire via le controller (la vue lui envoie l'info via post ou get par ex) qui loaderai une class ''GenerateUrl(url)" (par ex), puis ensuite tu renvoies dans la vue.

  3. #3
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2019
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2019
    Messages : 67
    Par défaut
    Bonjour,

    J'en suis conscient et j'aimerai respecter ce principe.

    Mais la solution que tu me proposes signifie que toutes les URL présentes sur la vue devraient être envoyés au controleur lors du chargement de la page... (via Javascript, Ajax ?) pour ensuite insérer correctement les liens.
    Par exemple pour la navbar principale ou tout autre lien.

    Bref ça me parait "compliqué", je souhaite respecter le principe MVC mais en gardant une certaine cohérence (effectuer systématiquement un second chargement des URL via AJAX après le chargement de la page, j'ai un peu de mal avec cette idée)

    Je reprends l'exemple de Symfony / TWIG qui permet d'appeller la fonction path(nom_url) qui est très efficace...

    Merci pour cette première réponse, je continue à chercher

  4. #4
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2018
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Thaïlande

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2018
    Messages : 119
    Par défaut
    Non c'est a dire qu au chargement de ta page les liens doivent etre inseres dynamiquement (meme si ils sont codes en dur dans un fichier a part).

    Je ne comprends pas trop ta question de lien dynamique.... mais bon de maniere generale ca se passe comme cela:

    Ils y a les liens de ton appli te servant a naviguer de page en page, ceux la se trouvent dans un fichier (xml par ex) et sont accessible a une class (RouteHandler par ex). Quand le visiteur click sur le lien l'url actionnee doit etre parse (REQUEST_URI()), puis comparee avec ceux existant (donc qui se trouvent dans le fichier xml, ou ailleurs). Si l'url match, le RouterHandler redirige sur le controller conrespondant qui actionnera les differentes actions necessaires et servira la vue avec tout ce qu'elle doit afficher. Si tu dois placer des liens dynamiquement c'est a ce moment (et donc via le controller, ou tout au moins le controller activera des class afin de les generer) qu'ils seront generes puis transmis a la vue qui les affichera.

    Je resume, mais l'idee est est la.

  5. #5
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2019
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2019
    Messages : 67
    Par défaut
    Sur mon appli Symfony hybride les liens ne sont pas dans un fichier XML mais directement en annotation sur chaque action de controleur (dans @Route)

    Controleur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    /**
    *@Route("/article/{article_id}", name="show_article")
    */
    public function showArticle(int $article_id) 
    {
        return $this->render('Vue/article.php', ['article_id' => $article_id]);
    }
    Le routing fait parfaitement le boulot, si je tape dans ma barre d'adresse http://url.com/article/1, la route correspond et le bon contrôleur est appelé.

    Mon seul et unique soucis, c'est que je ne veux pas écrire les liens en dur dans la vue (car si je modifie la route d'un contrôleur un jour, je devrais le modifier dans toutes les vues qui l'utilise).

    Si j'ai bien compris tu me suggères d'écrire dans ma vue un lien du style : <a href='REQUEST_URI(show_article)'>lien</a> et ensuite lorsque le lien est cliqué, le Router cherche la correspondance ?

    Désolé mais je patine un peu aujourd'hui

    EDIT : donc je me dis qu'au moment de charger ma Vue, juste avant, je cherche dans le fichier vue, tout ce qui contient {{ path('nom_de_la_route') }}, et je le remplace par la bonne URL...
    C'est effectivement ma méthode render qui est pour le moment incomplète.

  6. #6
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2018
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Thaïlande

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2018
    Messages : 119
    Par défaut
    Je citais REQUEST_URI() juste en exemple, dans ton cas ca ne sert a rien.

    Les liens dans ta vue, sont ceux de ta barre de navigation ?? ou a quoi servent ils ?

    EDIT : donc je me dis qu'au moment de charger ma Vue, juste avant, je cherche dans le fichier vue, tout ce qui contient {{ path('nom_de_la_route') }}, et je le remplace par la bonne URL...
    Si tes liens dépendent de ta vue, c'est a dire qu ils sont différents en fonction de chaque vue, c'est au niveau du controller qu ils doivent etre generer puis transmis a la vue (si tu veux les générer dynamiquement).

    Ou encore une autre solution serait de mettre un fichier de function (par ex) qui soit insere dans toutes les vues <?php require(fichierFonction.php); ?> et tu appel la fonction désire avec le chemin en paramètre comme ton exemple: fonctionPath('home'). Mais ca reste du codage en dur puisque que tu devras changer les paramètres manuellement.......
    En fait, que tu fasses
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <a href="/home">lien</a>
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <a href="<?= path('home'); ?>">lien</a>.
    , ca revient au meme ......

  7. #7
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2019
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2019
    Messages : 67
    Par défaut
    Il s'agit de tous les liens, les liens de la barre de navigation, les liens des formulaires (action), etc... et oui ils peuvent bien entendu différer d'une vue à l'autre.
    Tu as raison je crois que je vais finir par faire ça, inclure un simple fichier avec une fonction, cependant je sais pas si c'est trop propre et si ça respecte le MVC

    Dans l'exemple donné ça revient au même, mais si demain je change l'url de la route par exemple /home => /homepage, et bien vu que mes liens appelleront toujours le nom de la route (et non pas la route elle même), alors je n'aurai rien a modifier.

    Encore pire si la route contient des paramètres, au lieu d'écrire <a href="/{client_id}/commande/{commande_id}/{article_id}"> je vais plutôt l'écrire sous la forme <a href="{{ path('commande', [$client_id, $commande_id, $article_id]) }}.

    Mais j'aurai du poster mon topic sur le forum Symfony car c'est pas une évidence si on a jamais utilisé ce framework.
    En tout cas merci à toi, je crois que je me prends trop la tête

    Bonne journée

  8. #8
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2018
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Thaïlande

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2018
    Messages : 119
    Par défaut
    Perso je ne bosse pas avec Symphony, donc si il fournit un systhem pour generer tous les liens dynamiquement je ne sais pas.

    Par contre ce que je sais, c'est qu'en general dans une application, la barre de menu (et donc tous ses liens) est stoque dans un fichier separe puis injecte dans toutes les vues (<?php require(fichierNav.php); ?>), meme en MVC (POO). Comme ca modifiable a 1 seul endroit, et si tu veux faire 2 barres de menu differentes, et bien deux fichiers (nav1.php, nav2.php) que tu require() suivant la vue.

    Pour les autres liens, il n'y a aucun probleme a avoir un fichier de fonctions injecte (require()) dans toutes les vues, et distribuant les url. Ainsi si on doit en modifier, on les modifie une fois pour toutes dans ce fichier (inutile de le mettre en poo).

    En MVC, les infos distribuees par les vues proviennent du controlleur. Cependant l'integration de templates (header, nav, footer, par ex) se manage au niveau des vues elles memes.

    ps.Evidemment si le but de l'appli est de generer des liens dans tous les sens, adopter une logique au niveau du controller/framework sera preferable.

Discussions similaires

  1. [C#][2.0] Appel à une fonction dans global.asax
    Par lilianjee dans le forum ASP.NET
    Réponses: 2
    Dernier message: 05/10/2006, 15h58
  2. appel à une fonction dans la classe Action
    Par imane_bennouna dans le forum Struts 1
    Réponses: 3
    Dernier message: 07/08/2006, 11h09
  3. Appeler une fonction dans le body
    Par FredKéKé dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 05/04/2006, 10h43
  4. Appeler une fonction dans un autre cadre !
    Par rich25200 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 01/11/2005, 13h01
  5. Réponses: 7
    Dernier message: 10/09/2005, 16h49

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