Partage
  • Partager sur Facebook
  • Partager sur Twitter

MOOC Programmez en orienté objet en PHP

    9 juillet 2019 à 13:20:15

    Bonjour, j'ai fait un système pour faire une confirmation d'un compte par email mail quand je clique sur le lien dans le mail ça me met erreur 500. 

    Si quelqu'un peut m'aider 

    Merci

    -
    Edité par ArthurMascetti 9 juillet 2019 à 13:24:17

    • Partager sur Facebook
    • Partager sur Twitter
      9 juillet 2019 à 14:05:33

      Bonjour.

      ArthurMascetti a écrit:

      Bonjour, j'ai fait un système pour faire une confirmation d'un compte par email mail quand je clique sur le lien dans le mail ça me met erreur 500. 

      Si quelqu'un peut m'aider 

      Merci

      -
      Edité par ArthurMascetti il y a 28 minutes

      C'est que l'url du lien est incorrect, as-tu bien pensé à mettre l'url complète dans le mail, soit avec le nom d'hôte ?

      Tu devrais quand même vérifier que les paramètres nécessaires dans l'url sont bien présents et que leur valeur n'est pas vide au tout début du code, ou faire l'inverse, par exemple:

      if (empty($_GET['id']) || empty($_GET['token'])) {
          // Au moins un des paramètre de l'url est manquant ou vide
          // Créer un message pour en notifier l'utilisateur
          $_SESSION['flash']['danger'] = 'Lien invalide';
          header('Location: login.php');
          exit;
      }
      // Suite du code, pour le cas ou la première condition n'est pas rencontrée

      -
      Edité par Lartak 9 juillet 2019 à 14:06:15

      • Partager sur Facebook
      • Partager sur Twitter

      Face a quelqu'un pour qui l'on n'éprouve que de l'aversion et du mépris, les yeux d'un homme deviennent extrêmement froids et cruels.

        9 juillet 2019 à 19:12:50 - Message modéré pour le motif suivant : Merci d'utiliser le bouton code du forum pour insérer votre code


          9 juillet 2019 à 19:30:03

          BabouneSmith a écrit:

          Salut, j'ai une petite question sur le cours et plus précisément sur les interfaces. Je ne comprend pas à quoi cela sert d'implémenter une interface si c'est pour écrire toute ses fonctions dans la classe. Autant ne rien implémenter.

          Quelqu'un pourrait m'expliquer l'utilité, je ne la saisie pas en lisant le cours.


          Je vais essayer de t'expliquer.

          Pour utiliser une classe abstraite, il faut implémenter une autre classe qui va hériter de cette classe abstraite. Ce qui est également le cas d'une interface.

          Par contre une interface ne contient pas de propriétés, elle peut hériter en losange (la même interface peut être héritée plusieurs fois), ce qui n'est pas possible avec les classes, et toutes ses méthodes sont obligatoirement publiques. Ce sont là les principales différences avec une classe abstraite.

          Par ailleurs lorsqu'une classe hérite d'une interface, ta classe (peu importe la quelle), aura un comportement homogène. Alors que dans le cas d'une classe abstraite, qui peut en outre comporter des propriétés et des méthodes déjà implémentées (ce qui n'est pas le cas d'une interface), la classe qui hérite d'une classe abstraite doit avoir en quelque sorte un lien de parenté avec la classe abstraite.

          La manière dont moi je comprends la différence entre les deux, c'est qu'une classe (abstraite) peut se montrer plus contraignante qu'une interface (et encore ... tout dépend du contexte). Mais il n'y a pas de recette prédéfinie, il est possible d'implémenter les mêmes fonctionnalités avec des classes abstraites et avec des interfaces. Lorsque cette situation survient, à toi de choisir d'utiliser plutôt des classes abstraites ou des interfaces selon les besoins de ton application.

          Voilà ... j'espère que ça te permettra de méditer sur le sujet ;).

          V

          -
          Edité par vincent48 9 juillet 2019 à 19:40:23

          • Partager sur Facebook
          • Partager sur Twitter

          Vincent ERHART

          Formateur / Développeur web

            9 juillet 2019 à 19:37:13

            @ArthurMascetti Merci de ne pas poster de code en image, le forum dispose d'une fonctionnalité pour insérer le code. Utiliser le bouton code </> au dessus de la zone ou vous écrivez. Comme indiqué dans les règles du forum.

            • Partager sur Facebook
            • Partager sur Twitter
              9 juillet 2019 à 22:21:48

              Je ne vois d'erreur dans l'url j'ai bien reverifier. je t'envoi le code du register la ou il y a le "mail"

              <?php
              
              require_once 'includes/functions.php';
              if (session_status() == PHP_SESSION_NONE) {
              	session_start();
              }
              if (!empty($_POST)) {
              
              	$errors = array();
              	require_once 'includes/db.php';
              
              	if (empty($_POST['username']) || !preg_match('/^[a-zA-Z0-9_]+$/', $_POST['username'])) {
              		$errors['username'] = "Votre pseudo n'est pas valide (alphanumérique)";
              	} else {
              		$req = $pdo->prepare('SELECT id FROM users WHERE username = ?');
              		$req->execute([$_POST['username']]);
              		$user = $req->fetch();
              		if ($user) {
              			$errors['username'] = 'Ce pseudo est déjà pris';
              		}
              	}
              
              	if (empty($_POST['email']) || !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
              			$errors['email'] = "Votre email n'est pas valide";
              	} else {
              		$req = $pdo->prepare('SELECT id FROM users WHERE email = ?');
              		$req->execute([$_POST['email']]);
              		$user = $req->fetch();
              		if ($user) {
              			$errors['email'] = 'Cette email est déjà utilisé pour autre compte';
              		}
              	}
              
              	if (empty($_POST['password']) || $_POST['password'] != $_POST['cpassword']) {
              		$errors['password'] = "Vos deux mots de passe ne corrsepondent pas";
              	}
              
              	if (empty($errors)) {
              		$req = $pdo->prepare("INSERT INTO users SET username = ?, password = ?, email = ?, confirmation_token = ?");
              		$password = password_hash($_POST['password'], PASSWORD_BCRYPT);
              		$token = str_random(60);
              		$req->execute([$_POST['username'], $password, $_POST['email'], $token]);
              		$user_id = $pdo->lastInsertId();
              		mail($_POST['email'], 'Confirmation de votre compte', "Votre compte est presque près, cliquez sur ce lien afin de le valider :\n\nhttps://boyscote.000webhostapp.com/confirm.php?id=$user_id&token=$token");
              		$_SESSION['flash']['success'] = 'un email de confirmation vous a été envoyé pour valider votre compte';
              		header('Location: login.php');
              		exit();
              	}
              ?>



              • Partager sur Facebook
              • Partager sur Twitter
                10 juillet 2019 à 8:24:57

                vincent48 a écrit:

                BabouneSmith a écrit:

                Salut, j'ai une petite question sur le cours et plus précisément sur les interfaces. Je ne comprend pas à quoi cela sert d'implémenter une interface si c'est pour écrire toute ses fonctions dans la classe. Autant ne rien implémenter.

                Quelqu'un pourrait m'expliquer l'utilité, je ne la saisie pas en lisant le cours.


                Je vais essayer de t'expliquer.

                Pour utiliser une classe abstraite, il faut implémenter une autre classe qui va hériter de cette classe abstraite. Ce qui est également le cas d'une interface.

                Par contre une interface ne contient pas de propriétés, elle peut hériter en losange (la même interface peut être héritée plusieurs fois), ce qui n'est pas possible avec les classes, et toutes ses méthodes sont obligatoirement publiques. Ce sont là les principales différences avec une classe abstraite.

                Par ailleurs lorsqu'une classe hérite d'une interface, ta classe (peu importe la quelle), aura un comportement homogène. Alors que dans le cas d'une classe abstraite, qui peut en outre comporter des propriétés et des méthodes déjà implémentées (ce qui n'est pas le cas d'une interface), la classe qui hérite d'une classe abstraite doit avoir en quelque sorte un lien de parenté avec la classe abstraite.

                La manière dont moi je comprends la différence entre les deux, c'est qu'une classe (abstraite) peut se montrer plus contraignante qu'une interface (et encore ... tout dépend du contexte). Mais il n'y a pas de recette prédéfinie, il est possible d'implémenter les mêmes fonctionnalités avec des classes abstraites et avec des interfaces. Lorsque cette situation survient, à toi de choisir d'utiliser plutôt des classes abstraites ou des interfaces selon les besoins de ton application.

                Voilà ... j'espère que ça te permettra de méditer sur le sujet ;).

                V

                -
                Edité par vincent48 il y a environ 12 heures


                Super merci, j'comprend un peu mieux leurs différences
                • Partager sur Facebook
                • Partager sur Twitter

                ᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼





                ᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼᲼






























































































































































                  10 juillet 2019 à 16:16:22

                  @ArthurMascetti: Vérifies dans les logs du serveur pour les détails pour l'erreur 500.

                  Il est possible que tu aies une erreur au niveau PHP et comme l'affichage des erreurs PHP est désactivé en production, tu ne peux pas les voir directement, il te faut donc consulter les logs.

                  -
                  Edité par Lartak 10 juillet 2019 à 16:16:38

                  • Partager sur Facebook
                  • Partager sur Twitter

                  Face a quelqu'un pour qui l'on n'éprouve que de l'aversion et du mépris, les yeux d'un homme deviennent extrêmement froids et cruels.

                    11 juillet 2019 à 12:35:09

                    Lartak a écrit:

                    @ArthurMascetti: Vérifies dans les logs du serveur pour les détails pour l'erreur 500.

                    Il est possible que tu aies une erreur au niveau PHP et comme l'affichage des erreurs PHP est désactivé en production, tu ne peux pas les voir directement, il te faut donc consulter les logs.

                    -
                    Edité par Lartak il y a environ 20 heures


                    Merci, j'avais tout simplement oublier l'accolade pour fermer le esle

                    • Partager sur Facebook
                    • Partager sur Twitter
                      11 juillet 2019 à 12:46:05

                      ArthurMascetti a écrit:

                      Merci, j'avais tout simplement oublier l'accolade pour fermer le esle

                      Non, toutes les accolades des else sont bien fermées, si une accolade n'était pas fermée dans ton code, c'était celle du if de la ligne 7.
                      • Partager sur Facebook
                      • Partager sur Twitter

                      Face a quelqu'un pour qui l'on n'éprouve que de l'aversion et du mépris, les yeux d'un homme deviennent extrêmement froids et cruels.

                        24 juillet 2019 à 15:40:04

                        Bonjour, j'ai un problème avec le fichier bootstrap.php.

                        Voici le message d'erreur que j'ai, et pour voir mes fichiers, les voici sur github https://github.com/LR-LR/application_php

                        • Partager sur Facebook
                        • Partager sur Twitter
                          24 juillet 2019 à 15:47:19

                          LR-LR a écrit:

                          Bonjour, j'ai un problème avec le fichier bootstrap.php.

                          Voici le message d'erreur que j'ai, et pour voir mes fichiers, les voici sur github https://github.com/LR-LR/application_php

                          Il te suffit de lire le message d'erreur, qui te dit que le fichier ne peut pas être ouvert, car la permission est refusée.

                          De plus que ce n'est pas un dossier que PHP tente d'ouvrir mais un dossier (php_tp_3).

                          • Partager sur Facebook
                          • Partager sur Twitter

                          Face a quelqu'un pour qui l'on n'éprouve que de l'aversion et du mépris, les yeux d'un homme deviennent extrêmement froids et cruels.

                            25 juillet 2019 à 13:15:21

                            Lartak a écrit:

                            LR-LR a écrit:

                            Bonjour, j'ai un problème avec le fichier bootstrap.php.

                            Voici le message d'erreur que j'ai, et pour voir mes fichiers, les voici sur github https://github.com/LR-LR/application_php

                            Il te suffit de lire le message d'erreur, qui te dit que le fichier ne peut pas être ouvert, car la permission est refusée.

                            De plus que ce n'est pas un dossier que PHP tente d'ouvrir mais un dossier (php_tp_3).

                            Bonjour, merci pour ta réponse, est-ce que t'aurais une solution à ce problème sachant que je suis sur windows 10. Merci d'avance

                            • Partager sur Facebook
                            • Partager sur Twitter
                              9 août 2019 à 17:22:55 - Message modéré pour le motif suivant : Merci de créer votre propre sujet


                                5 septembre 2019 à 15:20:53

                                Bonjour a tous,

                                  J'aurais quelques questions à propos de l' "Activité_partie 3" du cours qui base cette conversation. Après avoir parcouru cette dernière (rapidement je l'avoue) j'ai vu que le sujet avait déjà été abordé. Pourtant, je ne crois pas pouvoir y trouver les réponses que je cherche. Ainsi donc.

                                1)  Comme il est précisé, les views doivent se chercher dans le cache avant d'etre générées. Mais qu'en est-il des données ? Qu'est-ce qu'on fait avec celles mises en cache à part les updater ? Je ne crois pas que taper dans le cache soit plus optimal que taper dans la BDD. En plus, comme le remarquait vincent48, les données sont inutiles au chargement des pages lorsque celles-ci sont en cache. La réponse est donc peut-être "rien", ce qui me conviendrait tres bien. Quoi qu'il en soit, j'aimerais en être assuré.

                                2) La vue d'accueil est-elle la seule à mettre en cache (cf premier item de la premiere ul de l' "objectif") ou bien faut-il toutes les y mettre ("toutes les données et vues suscitées doivent être mises en cache") ? La question pourrait se reformuler ainsi : "suscité" est-il à prendre dans le sens "sollicité par un client" ou bien dans le sens "sus-cité" ? Peut-etre que techniquement ca ne change pas grand-chose, je n'ai pas encore beaucoup réfléchi a cela. Sinon, il y a tout de même un petit paquet de views.

                                   D'un côté j'ai envie d'avoir un max de points et de l'autre, je n'ai pas envie de perdre du temps ou de de fournir un code inutilement complexe. En fait, j'aurais besoin de la réponse de quelqu'un qui connait déjà le barême (sans lui demander de le dévoiler, bien entendu). A ce sujet, au cas où le barême ne léveraient pas ces ambiguïtés et où ces dernières existeraient bien, mes questions seraient inutiles.

                                Bref, comment comprenez-vous la consigne sur ces deux points ? Merci pour vos éclaircissements.

                                -
                                Edité par Paul Vanderbeken 5 septembre 2019 à 15:24:11

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  11 septembre 2019 à 12:46:58

                                  Bonjour,

                                  @l'auteur de ce cours Mr Thuillier : je me permet humblement, telle une planche face à Bruce Lee, d'indiquer qu'une toute petite erreur s'est subrepticement logée dans le code du fichier App/Frontend/Templates/layout.php. 

                                  la ligne <?php if($user->isAuthenticated()) ?> mériterait de se situer une ligne en-dessous pour faire apparaître l'onglet Admin et pouvoir enfin s' Ôtenticatède....

                                  Comme je n'ai fait que recopier bêtement le fichier , cette erreur (probable erreur, on est plus sur de rien à l'échelle quantique) m' a coûté 2 jours de recherche... Si je peux venir en aide à certains comme moi, j'aurai fait pénitence....

                                  OUUUU je me trompe, mais alors phoque con messplique...

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    13 septembre 2019 à 17:37:58

                                    Volbos a écrit:

                                    Bonjour,

                                    @l'auteur de ce cours Mr Thuillier : je me permet humblement, telle une planche face à Bruce Lee, d'indiquer qu'une toute petite erreur s'est subrepticement logée dans le code du fichier App/Frontend/Templates/layout.php. 

                                    la ligne <?php if($user->isAuthenticated()) ?> mériterait de se situer une ligne en-dessous pour faire apparaître l'onglet Admin et pouvoir enfin s' Ôtenticatède....

                                    Comme je n'ai fait que recopier bêtement le fichier , cette erreur (probable erreur, on est plus sur de rien à l'échelle quantique) m' a coûté 2 jours de recherche... Si je peux venir en aide à certains comme moi, j'aurai fait pénitence....

                                    OUUUU je me trompe, mais alors phoque con messplique...


                                    Je crois que c'est voulu. Un utilisateur lambda ne doit pas avoir ce lien sous le nez, même si il ne dispose des identifiants. Si tu veux te connecter en mode admin, tu tapes [nom_de_ton_serveur]/admin dans la barre d'adresse de ton navigateur. Tu pouvais le savoir en regardant un des deux fichiers routes.xml. C'est ce que j'ai fait dès que j'ai voulu accéder à cette page.
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      14 septembre 2019 à 14:40:22

                                      Paul Vanderbeken a écrit:

                                      Volbos a écrit:

                                      Bonjour,

                                      @l'auteur de ce cours Mr Thuillier : je me permet humblement, telle une planche face à Bruce Lee, d'indiquer qu'une toute petite erreur s'est subrepticement logée dans le code du fichier App/Frontend/Templates/layout.php. 

                                      la ligne <?php if($user->isAuthenticated()) ?> mériterait de se situer une ligne en-dessous pour faire apparaître l'onglet Admin et pouvoir enfin s' Ôtenticatède....

                                      Comme je n'ai fait que recopier bêtement le fichier , cette erreur (probable erreur, on est plus sur de rien à l'échelle quantique) m' a coûté 2 jours de recherche... Si je peux venir en aide à certains comme moi, j'aurai fait pénitence....

                                      OUUUU je me trompe, mais alors phoque con messplique...


                                      Je crois que c'est voulu. Un utilisateur lambda ne doit pas avoir ce lien sous le nez, même si il ne dispose des identifiants. Si tu veux te connecter en mode admin, tu tapes [nom_de_ton_serveur]/admin dans la barre d'adresse de ton navigateur. Tu pouvais le savoir en regardant un des deux fichiers routes.xml. C'est ce que j'ai fait dès que j'ai voulu accéder à cette page.


                                      cqfd !!! Ça ne m'était vraiment pas venu à l'esprit même en regardant (et pas qu'une fois) le routes.xml

                                      Je savais bien que le bonhomme ne pouvait pas se tromper...

                                      Merci Paul

                                      Et je viens de m'apercevoir que si j'avais bien compris mon .htaccess j'aurai également évité de poster ...m'enfin

                                      ..la route est encore longue...

                                      -
                                      Edité par Ryme2402 14 septembre 2019 à 15:08:20

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        15 septembre 2019 à 11:42:48

                                        Volbos a écrit:

                                        cqfd !!! Ça ne m'était vraiment pas venu à l'esprit même en regardant (et pas qu'une fois) le routes.xml

                                        Je savais bien que le bonhomme ne pouvait pas se tromper...

                                        Merci Paul

                                        Et je viens de m'apercevoir que si j'avais bien compris mon .htaccess j'aurai également évité de poster ...m'enfin

                                        ..la route est encore longue...

                                        -
                                        Edité par Volbos il y a environ 20 heures

                                        Content t'avoir pu t'apporter quelque chose :-)

                                        D'autant plus que c'est une première, je n'avais encore jamais répondu a quelqu'un sur un forum.



                                        -
                                        Edité par Paul Vanderbeken 15 septembre 2019 à 11:43:40

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          16 septembre 2019 à 22:52:09

                                          Bonjour à tous,

                                          Je reviens sur un message que j´ai posté plus haut. J´y posais quelques questions au sujet de l´activité finale, qui n´ont pas reçues de réponses. Peut-être que personne n'a pu me répondre parmi ceux qui m'ont lu. Quoi qu´il en soit, j'ai fait l'activité et j'ai vu sa correction. Je vais donc répondre à ce que je demandais et ajouter certaines choses, dans l'espoir de pouvoir aider quelqu'un.

                                          Chaque liste de commentaires et chaque news doivent être mises en cache (pas la liste des news). Quant aux pages, une seule y est mise : L´index de Frontend. Contrairement à la consigne, le barême indique clairement que seuls ces élements sont attendus dans la cache, et le corrigé confirme cela. Ainsi les pages appartenant au backend ne se mettent pas en cache, et il ne faut pas tenir compte du ¨toutes les données et vues suscitées doivent être mises en cache¨. Cela répond à ma deuxième question et la première ne se pose plus avec le peu de pages qu´il faut mettre en cache.

                                          Il reste tout de même un problème. La page d´accueil peut avoir deux formes, selon l´identification éventuelle d´un administrateur. En même temps, la consigne impose qu´un seul fichier la représente dans le cache : Frontend_news_index. À première vue, cela semble contradictoire. D´ailleurs, tous les devoirs que j´ai corrigé bugaient à cause de ce manque de distinction (quand je passais en mode admin au milieu de ma navigation, l´appli chargeait la page d´accueil en mode non-admin, et vice-versa quand j´effaçais les cookies). Perso, je me suis permis d´ajouter un suffixe ´_admin´ aux fichiers quand il s´agissait du mode admin.

                                          Mais comment bien faire tout en respectant la consigne ? J´ai eu la réponse en regardant la correction : C´est le contenu du $content invoqué dans layout.php et page.php qu´il faut mettre en cache. Grosso modo, il s´agit de tout sauf du layout. Or c´est bien ce dernier qui diffère entre les deux versions. La réponse que je donne là pouvait donc se deviner. Pour être honnête, il s´agit même à peu près de ce que demandait la consigne. Mais qui l´a comprise ainsi ?? En tout cas, personne parmi moi et ceux dont j´ai vu le boulot.

                                          Vous l´aurez compris, je trouve que cette consigne manque sévèrement de clarté. Elle a pourtant le rôle de consigne. En plus de cela, l´exercice se base sur un projet (trop) difficile à bien s´approprier et très mal expliqué dans le cours (bien que ce dernier reste potable par ailleurs et que je sois content de ce qu´il m´ait appris).

                                          De mon côté j´ai renoncé à comprendre le code du projet à l´aide du cours, je me suis plongé directement dedans, j´ai fini par bien le comprendre, puis j´ai relu les explications. Et là franchement elles m´ont mis en colère. Quant au projet, je doute de la qualité de son implémentation. Je suis presque convaincu qu´on peut faire plus propre et plus clair (ce qui ne serait pas du luxe concernant ce dernier point) tout en obtenant une bibliothèque (réutilisable ailleurs, par définition), une architecture MVC, le respect de l´encapsulation, une bonne maintenabilité, etc...

                                          En conclusion, je dirais que cette activité et sa consigne sont à revoir, et j´espère pour les suivants que ce sera fait. D´ailleurs, 33 jours d´attente en moyenne pour être corrigés !! Pour un cours aussi crucial, n´est-ce pas étrange qu´aussi peu aillent jusqu´au bout ?

                                          -
                                          Edité par Paul Vanderbeken 16 septembre 2019 à 23:06:04

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            17 septembre 2019 à 7:27:08

                                            Bonjour Paul Vanderbeken

                                            Je suis un eleve comme toi (je veux dire que je n'ai rien a voir avec l'equipe d'openClassRooms). Je me debrouile seul et therme d'apprentissage et me contente de suivre les formations d'openClassRooms. Le cours ''Programmer en orientee objet en php" est de mon point de vue tout simplement 'EXCELENT', il permet d'approfondir les connaissances du language php ainsi que d'apprendre a coder en Orientee Objet. Il est certe plutot corse mais il n'y a pas d'imperatif temps ! c'est a dire que chacun va a son rytme, les meilleurs vite, les moins bon, et bien comme partout il faut plus de travail personnel !!! Sur le web il n'y a pas que 'OpenClassRooms' donc pour ceux qui ne saississent pas tout immediatement, ou bien pour qui certaines explications restent floues il faut creuser, passer un peu plus de temps a rechercher des informations complementaires ailleurs...... Tout simplement y passer le temps necessaire afin de comprendre.  

                                            En ce qui concerne la derniere partie du cours la mise en place de l'application, ca doit bien faire 2-3 mois (si c'est pas plus) que je suis dessus, excuse moi, mais cette derniere partie est encore une fois 'EXCELENTE !!!' elle permet de comprendre le fonctionnement d'une appli, de voir les rapports entre les class mere/fille, les differentes appli, les differents modules, etc.,c'est juste parfait !!!!! Ok l'enonce du devoir final est un peu flou, mais encore une fois si on prends le temps de rechercher, on trouve des reponses sur le forum d'openClassRooms et ailleurs.... Et puis rechercher par soi-meme, reflechir, trouver des solution fait parti de l'apprentissage. (et si au devoir final on a pas 10/10, ou est le probleme ? on a fait de notre mieux c'est l'essentiel. Faire des erreurs fait partie de l'apprentissage, c'est comme ca que l'on progresse.)

                                            Dernier point, n'oublions pas que ces cours sont GRATUIT (pour ceux qui paient ils sont un suivit par un prof) !!!!! T'en connait beaucoup toi des formations qui te "donnent" ce que te donne OpenClassRooms, ce que "DONNE" Monsieur Victor Thuillier (pour ce cours) et les autres Profs qui ont pris le temps de rediger des cours COMPLET ! Des fois, en lisant certains messages, j'ai l'impression que certains trouvent ca normal........ !!!!

                                            Moi je dis MERCI Mr Thuillier (et tous les profs d'OpenClassRooms), des cours comme comme ca, meme si c'est pas toujours facile, j'en veut bien d'autre !

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              18 septembre 2019 à 13:47:45 - Message modéré pour le motif suivant : Merci d'utiliser le bouton code du forum pour insérer votre code


                                                18 septembre 2019 à 14:59:21

                                                Bonjour @djedjethai,

                                                   J'apprécie beaucoup le site d'Openclassrooms (et le fait que ce soit gratuit). J'y ai déjà suivi une quinzaine de cours que j'ai presque tous terminés, ce qui me donne des élements de comparaison. Ainsi, je crois pouvoir dire que le cours de Mr Thuillier et son activité sont loin d'être "excellents" par rapport à ceux des autres, et je persiste à dire qu'ils mériteraient d'être revus. Quant au fait qu'ils les aient "donnés", ça m'étonnerait qu'il les aient rédigés gratuitement.

                                                -
                                                Edité par Paul Vanderbeken 18 septembre 2019 à 15:03:35

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  18 septembre 2019 à 18:03:25

                                                  Bonsoir,

                                                  J'ai à mon actif plus de 100 cours suivi sur OpenClassrooms, ce cours fait partie certainement des plus difficiles que j'ai suivi. La dernière activité m'a fait renoncer pendant plus de 4 mois tout en cherchant des solutions et faisant d'autres cours. Puis je me suis lancé et j'ai terminé cette activité. Quelle fierté d'avoir réussi et d'avoir obtenu la certification. Je rejoins l'avis de Djedjethai. Il faut beaucoup réfléchir, chercher, faire le métier comme diraient les cyclistes dont je fais aussi partie.

                                                  Bien à vous

                                                  -
                                                  Edité par Philippe2463 18 septembre 2019 à 18:04:01

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                  La chute n'est pas un échec, l'échec c'est de rester là où on est tombé!
                                                    19 septembre 2019 à 11:02:01

                                                    Philippe2463 a écrit:

                                                    Je rejoins l'avis de Djedjethai. Il faut beaucoup réfléchir, chercher, faire le métier

                                                    Sur ce point, je crois bien qu'on est tous d'accord.

                                                    -
                                                    Edité par Paul Vanderbeken 19 septembre 2019 à 11:03:15

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      20 septembre 2019 à 14:48:02

                                                      Paul Vanderbeken a écrit:

                                                      Bonjour à tous,

                                                      Je reviens sur un message que j´ai posté plus haut. J´y posais quelques questions au sujet de l´activité finale, qui n´ont pas reçues de réponses. Peut-être que personne n'a pu me répondre parmi ceux qui m'ont lu. Quoi qu´il en soit, j'ai fait l'activité et j'ai vu sa correction. Je vais donc répondre à ce que je demandais et ajouter certaines choses, dans l'espoir de pouvoir aider quelqu'un.

                                                      Chaque liste de commentaires et chaque news doivent être mises en cache (pas la liste des news). Quant aux pages, une seule y est mise : L´index de Frontend. Contrairement à la consigne, le barême indique clairement que seuls ces élements sont attendus dans la cache, et le corrigé confirme cela. Ainsi les pages appartenant au backend ne se mettent pas en cache, et il ne faut pas tenir compte du ¨toutes les données et vues suscitées doivent être mises en cache¨. Cela répond à ma deuxième question et la première ne se pose plus avec le peu de pages qu´il faut mettre en cache.

                                                      Il reste tout de même un problème. La page d´accueil peut avoir deux formes, selon l´identification éventuelle d´un administrateur. En même temps, la consigne impose qu´un seul fichier la représente dans le cache : Frontend_news_index. À première vue, cela semble contradictoire. D´ailleurs, tous les devoirs que j´ai corrigé bugaient à cause de ce manque de distinction (quand je passais en mode admin au milieu de ma navigation, l´appli chargeait la page d´accueil en mode non-admin, et vice-versa quand j´effaçais les cookies). Perso, je me suis permis d´ajouter un suffixe ´_admin´ aux fichiers quand il s´agissait du mode admin.

                                                      Mais comment bien faire tout en respectant la consigne ? J´ai eu la réponse en regardant la correction : C´est le contenu du $content invoqué dans layout.php et page.php qu´il faut mettre en cache. Grosso modo, il s´agit de tout sauf du layout. Or c´est bien ce dernier qui diffère entre les deux versions. La réponse que je donne là pouvait donc se deviner. Pour être honnête, il s´agit même à peu près de ce que demandait la consigne. Mais qui l´a comprise ainsi ?? En tout cas, personne parmi moi et ceux dont j´ai vu le boulot.

                                                      Vous l´aurez compris, je trouve que cette consigne manque sévèrement de clarté. Elle a pourtant le rôle de consigne. En plus de cela, l´exercice se base sur un projet (trop) difficile à bien s´approprier et très mal expliqué dans le cours (bien que ce dernier reste potable par ailleurs et que je sois content de ce qu´il m´ait appris).

                                                      De mon côté j´ai renoncé à comprendre le code du projet à l´aide du cours, je me suis plongé directement dedans, j´ai fini par bien le comprendre, puis j´ai relu les explications. Et là franchement elles m´ont mis en colère. Quant au projet, je doute de la qualité de son implémentation. Je suis presque convaincu qu´on peut faire plus propre et plus clair (ce qui ne serait pas du luxe concernant ce dernier point) tout en obtenant une bibliothèque (réutilisable ailleurs, par définition), une architecture MVC, le respect de l´encapsulation, une bonne maintenabilité, etc...

                                                      En conclusion, je dirais que cette activité et sa consigne sont à revoir, et j´espère pour les suivants que ce sera fait. D´ailleurs, 33 jours d´attente en moyenne pour être corrigés !! Pour un cours aussi crucial, n´est-ce pas étrange qu´aussi peu aillent jusqu´au bout ?

                                                      -
                                                      Edité par Paul Vanderbeken 16 septembre 2019 à 23:06:04


                                                      Bonjour Paul,

                                                      Tout d'abord, je suis moi-même enseignant (Agrégé) en Informatique Industrielle depuis 26 ans (donc pas vraiment novice...) dans une université et autant j'ai apprécié la qualité dans le ton, la méthodologie et l'approche de Mathieu Nebra dont j'ai fait déjà beaucoup de cours, autant je trouve, malheureusement, très difficile et complexe ce cours de Mr Thuillier sur ce cours sur la poo php.

                                                      Contrairement à toi, je n'ai pas survolé le cours mais au fils du cours j'ai toujours cherché à écrire le code au fur et à mesure de chaque étape et avant de lire le code proposé. J'ai donc retapé entièrement le code (dans les règles de l'Art suivant les consignes du cours sur les MCV de Mathieu Nebra avec notamment tous les commentaire et noms de variable en anglais - mieux vaut un mauvais Anglais qu'un bon Français (cours MCV)).

                                                      Aussi, je considère ce cours vraiment difficile et les explications parfois peu claires en première approche, les partie bien trop longues et je comprends que beaucoup puisse abandonner. Toutefois, j'utilise phpstorm (JetBrains) qui possède un débugger qui m'a permit de suivre pas à pas chaque étape et notamment la construction des appels de classes et des différentes méthodes. au final, effectivement le code est "intelligent" et fonctionne bien. Après ce passage par mon debugger je comprends bien mieux les explications mais je maintiens que ce cours tel qu'il est présenté est très difficile et ses différentes parties si longues (j'ai tout imprimé !) qu'ils sont malheureusement décourageantes.

                                                      Toutefois, il faut reconnaître qu'il très complet et pour l'avoir suivi de bout en bout très enrichissant.

                                                      J'en suis maintenant à cette fameuse activité 3 et tout comme les autres je sèche franchement. C'est pourquoi je te remercie pour le message cité ci-dessus qui éclaire un peu ma lanterne. J'ai commencé ce cours le 28 juillet fait au passage de 9/08 au 1/09 et obtenu le certificat sur le cours de Mathieu Nebra sur l'architecture MCV en PHP.

                                                      Alors tu écris :

                                                      Chaque liste de commentaires et chaque news doivent être mises en cache (pas la liste des news). Quant aux pages, une seule y est mise : L´index de Frontend. Contrairement à la consigne, le barême indique clairement que seuls ces élements sont attendus dans la cache, et le corrigé confirme cela.

                                                      C'est je crois une mauvaise interprétation de la dite consigne puisqu'il est demandé :

                                                      • La vue correspondante à la page d'accueil du site.

                                                      Or si l'on suit dans le code l'appel de la page d'accueil du site, il faut regarder le fichier .htaccess qui appelle le fichier bootstrap.php avec comme application par défaut le Frontend. Et donc par défaut c'est bien la page index.php du fronted qui est la vraie page d'accueil du site. et c'est donc bien elle qu'il est demandé de mettre en cache.

                                                      D'autre part, il semble illogique de mettre en cache les vues du Backend (qui nécessite effectivement un changement manuel du chemin d'appel http en ajoutant '/admin/' à celle-ci) puisque les fonctions d'administrations (ajout, modification ou suppression) nécessitent un accès direct à la base de données elle-même.

                                                      Ton post m'éclaire davantage aussi sur ce sujet de TP. Ce qu'il faut comprendre c'est que dans un premier temps il explique le rôle d'un cache puis vient la consigne qui défini ce que nous devons faire. En fait c'est le titre "Votre mission" qui est à mon avis une erreur pour ce sujet. "Le rôle d'un cache" aurait été moins cause de confusion.

                                                      Fort de tes commentaires, je vais peut-être avancer un peu et je t'en remercie. Je pense revenir ici bientôt puisque c'est pour moi, la première fois que j'interviens sur le forum.

                                                      Bonne journée

                                                      Patrick

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        22 septembre 2019 à 0:01:59

                                                        Bonjour Patrick,

                                                          Ayant aussi suivi le cours de bout en bout, je l'ai également trouvé très enrichissant. Je dois au moins lui reconnaître cela après ce que j'ai dit de de son activité. Et bien que je sois en désaccord sur certains points concernant l'implémentation du projet, il reste fonctionnel, évolutif et sa bibliothèque est digne d'intérêt.

                                                          Comme tu disais, la consigne parle bien de "La vue correspondante à la page d'accueil du site". Mais elle dit plus loin "¨toutes les données et vues suscitées", ce qui m'a fait tiquer. Je crois qu'il voulait dire "sus-citées" et peu importe. Apparemment ça ne met pas grand monde en confusion et je voulais surtout parler d'autre chose.

                                                        Je pense que je n'ai pas été très clair sur un point. La page d'accueil (enregistrée dans Frontend_news_index) peut avoir deux menus différents selon l'identification de l'utilisateur (il peut y avoir "admin" et "Insérer une news" en plus de "accueil", ou quelque chose du même genre). Il ne faut donc pas mettre en cache le menu, mais seulement le $content (précisé dans mon autre message).

                                                        En fait, j'aurais pu me contenter d'écrire ces dernières lignes au lieu de mon pavé précédent.

                                                        Bonne continuation avec l'activité et le reste

                                                        -
                                                        Edité par Paul Vanderbeken 22 septembre 2019 à 0:05:32

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          22 septembre 2019 à 14:56:18

                                                          Bonjour Paul,

                                                          Et merci pour cette réponse et cette précision. Et pour tous ceux qui liront ce message, si j'ai été un peu critique sur ce cours, j'ai également dit que je le trouvais très complet et que j'ai beaucoup appris, compris des notions qui étaient restées floues dans mon esprit et qu'au final, tous les efforts faits pour suivre et comprendre l'ensemble de ce cours sont très valorisants. Je crois que c'est le sujet lui-même qui est complexe et je salue donc l'auteur de ce cours l'avoir abordé.

                                                          En fait, j'ai passé la journée d'hier à travailler sur cette activité. Mon but au départ était de mettre en cache uniquement l'index du Fronted, comme je l'avais écrit. Alors, j'ai fait comme le prof : réfléchissons, schématisons (très utile au passage ;)). 

                                                          Pour ne pas (comme le précise le sujet) appeler le contrôleur de news, j'ai créé :

                                                          • une nouvelle classe abstraite (base de fichier cache)
                                                          • deux classes filles l'une pour le cache des vues l'autre pour le cache des données.

                                                          J'ai instancié ces deux dernières classes directement dans le constructeur de l'Apllication. Puis en modifiant la méthode execute() du BackController, je construit le nom du fichier à mette en cache avec les données disponible à ce niveau et déroute cette méthode (remarque j'utile la version PHP 7.3.8 fortement typée)

                                                              public function execute(): void
                                                              {
                                                                  $method = 'execute'.ucfirst($this -> action);
                                                                  if (!is_callable([$this, $method]))
                                                                  {
                                                                      throw new \RuntimeException('L\'action "'.$this -> action.'" n\'est pas définie sur ce module');
                                                                  }
                                                                  else
                                                                  {
                                                                      $cacheFileName
                                                                          = ucfirst($this -> app -> name()).$this -> module.ucfirst($this -> action).'.txt';
                                                                      
                                                                      $viewCacheFile = $this -> app -> viewCacheFile();
                                                                      $viewCacheFile -> setCacheFileName($cacheFileName);
                                                                      if ($viewCacheFile -> isExists() && $viewCacheFile -> isValid())
                                                                      {
                                                                          exit($viewCacheFile -> readCacheContent());
                                                                      }
                                                                      else
                                                                      {
                                                                          $this -> $method($this -> app -> httpRequest());
                                                                      }
                                                                  }
                                                              }
                                                          

                                                          Puis, en modifiant la méthode getGeneratedPage() de la classe Page :

                                                              public function getGeneratedPage(): string
                                                              {
                                                                  if (!file_exists($this -> contentFile))
                                                                  {
                                                                      throw new \RuntimeException('La vue spécifiée n\'existe pas.');
                                                                  }
                                                                  
                                                                  if (!$viewCacheFile = $this -> app -> viewCacheFile() -> isValid())
                                                                  {
                                                                      $user = $this -> app -> user();
                                                                      
                                                                      extract($this -> vars, null);
                                                                      
                                                                      ob_start();
                                                                      require $this -> contentFile;
                                                                      $content = ob_get_clean();
                                                                      
                                                                      ob_start();
                                                                      require __DIR__.'/../../App/'.$this -> app -> name().'/Templates/layout.php';
                                                                      
                                                                      $this -> app -> viewCacheFile() -> writeCache(ob_get_contents());
                                                                      return ob_get_clean();
                                                                  }
                                                                  else
                                                                  {
                                                                      return $this -> app -> viewCacheFile() -> readCacheContent();
                                                                  }
                                                              }
                                                          

                                                          Et là, à ma grande surprise, je me suis aperçu que j'avais créé absolument toutes les vues en cache du frontend et du Backend :

                                                          Vues mise en cache

                                                          et en plus cela marche (enfin presque il manque tout de même les données mais je n'ai pas fini). Volontairement, je ne décris pas mes nouvelles classes.

                                                          Si maintenant, tu me dis qu'il n'y a que le $content à mette en cache… Cela m'oblige à revoir cela.

                                                          Peux-tu (sans me dévoiler la solution) me dire si je suis sur la bonne voie ?

                                                          Bonne journée

                                                          Patrick



                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            22 septembre 2019 à 21:22:12

                                                            Bonjour Patrick,

                                                              Ce résultat n'est pas très surprenant si tu ne filtres pas les pages sur lesquelles ton code s'applique :-) et il montre que tu tiens le bon bout. Mais... Il y a plusieurs mais. J'espère que je ne te vexerai pas en en parlant ouvertement dans la suite, je sais que tu es déjà d'un certain niveau.

                                                            Peut-être que je me trompe, mais il me semble que tu te trouves dans un de ces deux cas (à l'heure où tu as posté) :
                                                              - Tu n'as pas beaucoup essayé ce que donne ton code.
                                                              - Ton code ne va pas chercher les pages en cache.

                                                            Sinon tu aurais vu plusieurs trucs qui ne fonctionnent pas. Par exemple, la page listant les commentaires de la news 1 ne peut pas se mettre en cache avec les noms de fichier recommandés (que tu ne respectes pas tout à fait, mais peu importe). Admettons qu'elle y soit et que tu veuilles regarder les commentaires de la news 2. L'application va alors voir l'existence et la validité de Frontend_news_show, ce qui aura pour effet l'affichage des commentaires de la news 1 au lieu de la 2.

                                                            Plus subtil, les pages comportant des formulaire ne doivent pas non plus être mises en cache. L'attribut action des form est toujours vide (ou presque toujours, je n'ai pas fait de vérification systématique). Par conséquent, ces pages se rechargent à chaque submit. Cela fonctionne très bien si la méthode execute est exécutée, mais si on la court-circuite avec le cache, la page se recharge lors du submit comme elle était à la base (avec un formulaire vierge) et sans qu'aucun traitement ne soit fait. Bref, le bouton de soumission n'a plus du tout l'effet escompté, mais un effet de reset.

                                                            Naturellement, ces disfonctionnements n'apparaissent que si ton programme va bien chercher les pages en cache. Je ne connais pas phpstorm, mais puisqu'il intègre un debugger, tu devrais pouvoir le vérifier facilement. Sinon voici un petit snippet à mettre dans bootstrap.php :

                                                            function debugLog($msg)
                                                            {
                                                              $handle = fopen(__DIR__.'/../log.txt', 'a+');
                                                              fputs($handle, "$msg\n");
                                                              fclose($handle);
                                                            }
                                                            

                                                            Il suffit ensuite d'ajouter debugLog($this -> app -> viewCacheFile() -> readCacheContent()); avant ton return $this -> app -> viewCacheFile() -> readCacheContent();. Après, bien sûr, on peut loguer en plus des séparateurs et il faut faire tourner l'appli et regarder log.txt. Si une page a bien était chargée à partir du cache, tu y verras alors son code HTML (à moins que tu ne choisisses de loguer autre chose).

                                                            À part ça, j'ai l'impression de ne pas encore avoir été compris sur le point que je resoulevais dans mon dernier message. C'est pourquoi je te propose ce petit test, admettant que ton programme charge bien les pages en cache :
                                                              - Efface les views en cache
                                                              - Efface les données de navigation concernant l'adresse où tourne ton projet pour ne plus être en mode admin.
                                                              - Charge la page d'accueil pour vérifier que tu es bien en mode normal (Il y a seulement "Accueil" dans le menu du layout).
                                                              - Essaie de répéter les deux derniers points si tu vois "Admin" dans le menu du layout.
                                                              - Passe en mode admin en chargeant la page de connexion (il est probable que tu doives auparavant l'empêcher de se mettre en cache, car il y a un formulaire).
                                                              - Reviens sur la page d'accueil.

                                                            Normalement, l'accueil s'affichera sans qu'il y ait "Admin" et "Ajouter une news" dans le menu du layout, alors qu'ils devraient y être. Voilà pourquoi il faut se restreindre au $content. Ou bien il faut choisir deux noms distincts au lieu de Frontend_news_admin, c'est la solution que j'ai adoptée mais elle s'écarte un peu de la consigne.

                                                            Autre détail, il faut laisser les executeDelete* s'exécuter et éviter que le cache s'en mêle, tu comprendras sans doute pourquoi.

                                                            J'espère que ma réponse te conviendra,

                                                            Paul

                                                            -
                                                            Edité par Paul Vanderbeken 22 septembre 2019 à 22:24:09

                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                              26 septembre 2019 à 12:34:57

                                                              Paul Vanderbeken a écrit:

                                                                Ce résultat n'est pas très surprenant si tu ne filtres pas les pages sur lesquelles ton code s'applique :-) et il montre que tu tiens le bon bout. Mais... Il y a plusieurs mais. J'espère que je ne te vexerai pas en en parlant ouvertement dans la suite, je sais que tu es déjà d'un certain niveau.

                                                              Peut-être que je me trompe, mais il me semble que tu te trouves dans un de ces deux cas (à l'heure où tu as posté) :
                                                                - Tu n'as pas beaucoup essayé ce que donne ton code.
                                                                - Ton code ne va pas chercher les pages en cache.

                                                              Sinon tu aurais vu plusieurs trucs qui ne fonctionnent pas. Par exemple, la page listant les commentaires de la news 1 ne peut pas se mettre en cache avec les noms de fichier recommandés (que tu ne respectes pas tout à fait, mais peu importe). Admettons qu'elle y soit et que tu veuilles regarder les commentaires de la news 2. L'application va alors voir l'existence et la validité de Frontend_news_show, ce qui aura pour effet l'affichage des commentaires de la news 1 au lieu de la 2.

                                                              Edité par Paul Vanderbeken 22 septembre 2019 à 22:24:09


                                                              Bonjour Paul,

                                                              Rassures toi, je ne me formalise pas du tout. Nous sommes tous là pour apprendre et/ou nous perfectionner, et je te remercie pour tes conseils.

                                                              Tu avais raison sur trois points

                                                              • Je n'avais pas tester à fond le fonctionnement !
                                                              • Effectivement avec cette première solution, la page d'accueil était statique et chaque lien fonctionnait mais renvoyait tous sur la première news et l'enregistrait sous un autre nom.
                                                              • Enfin, les noms de fichiers qui ne respectait pas la consigne effectivement. Bon, cela c'était facile à corriger.

                                                              Toutefois le cache fonctionnait dans le principe et lorsque que la page existait c'est bien vers elle qu'était redirigé l'application.

                                                              Maintenant, j'ai beaucoup travaillé depuis et corrigé ces problèmes. J'ai envoyé hier soir mon travail... sans le fichier sql, je viens de l'envoyer à part j'espère que cela sera accepté. 

                                                              Bon, j'ai vu la correction, effectivement c'est assez subtil et différent de ce que j'ai réalisé. Toutefois, je respecte point par point les consignes alors je verrai bien. Je suis tout de même en colère d'avoir fait cet oubli stupide !

                                                              Je vais corriger les trois exercices maintenant.

                                                              Dans tous les cas, merci.

                                                              Patrick

                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              MOOC Programmez en orienté objet en PHP

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              • Editeur
                                                              • Markdown