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 :

Revision d'un vieux site en PHP/MySQL avec le format actuel


Sujet :

PHP & Base de données

  1. #21
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par RinaBK Voir le message
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function tableExists($table) {
    	try {
    		$pdo = C_PDO::getC();
    		$result = $pdo->query("SELECT 1 FROM $table LIMIT 1");
    	}
    	catch (Exception $e) {
    		return FALSE;
    	}
    	return $result !== FALSE;
    }
    Attention ! pour lever les erreurs de pdo c'est catch(PDOException $e). Sans le préfixe PDO c'est pour lever les erreurs de PHP et non pas les erreurs de PDO. D'ailleurs, si besoin on peut chainer les deux, un catch(PDOException $e) pour lever les erreurs PDO et un catch (Exception $e) pour lever les erreurs PHP si tu utilises du code php qui émet des exceptions ou si tu les crées toi-même avec throw new Exception.
    Citation Envoyé par RinaBK Voir le message
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function creationtable($table,$requete) {
    	global $sitePrefixe;
     
    	try {
    		$connexion = C_PDO::getC();
    		$requete = 'CREATE TABLE '.$table.' '.$requete.');';
    		$stmt = $connexion->exec($requete);
    	}
    	catch(PDOException $e) {
    		exit($e->getMessage());
    	}
    	return $stmt ? "Création de la table terminée;" : "Impossible de créer la table";
    }
    exec retourne le nombre de lignes affectées, donc si tu crée une table $stmt va retourner 0. Et si tu faisais plutôt une requête préparée ? Après il existe aussi la syntaxe CREATE TABLE IF NOT EXISTS si tu n'as pas besoin d'avoir des fonctions distinctes.

    Autre chose, tu peux mettre n'importe quel code dans le catch. Si tu veux retourner l'erreur sans être éjecter de la page tu peux tout aussi bien faire $erreur = $e->getMessage() puis utiliser $erreur pour l'afficher où tu veux dans ta page.

    Et houla que c'est pas beau les variables globales. Bon là tu ne t'en sert pas, tu pourrais donc la supprimer, mais ça aussi ça fait partie de l'ancien temps. Soit tu passes ta variable en paramètre dans tes fonctions ou dans l'initialisation de tes classes, soit tu utilises une constante.

    Citation Envoyé par RinaBK Voir le message
    Donc, je pense avoir compris le principe de travailler en PHP orienté objets, si c'est bien le terme de cette méthode
    Je vais donc, continuer à corriger toute ma partie administration en utilisant cette méthode!
    Heu non c'est pas tout à fait ça la programmation orienté objet, un objet c'est... une classe.

    Et au fait si tu nous faisais une petite classe pour grouper les deux fonctions ci-dessus si tu as réellement besoin d'en avoir deux.

    Après la programmation objet ne se résume pas à grouper des fonctions dans une classe. C'est un début mais cela ne se résume pas à ça. Cela peut servir pour créer plusieurs instances, pour partager des variables communes entre différentes fonctions, pour hériter d'autres classes ou de collections de fonctions (trait) qui seront accessibles via le même objet, pour configurer des objets etc. Comme déjà dit, tu peux regarder les exemples des scripts côté formulaire ou côté serveur dans ce module d'upload pour te donner un exemple concret et utilisable. Cela sert à faciliter l'usage et la programmation en fournissant des méthodes utiles sans avoir à se soucier de tout le bin's qu'il y a derrière pour faire marcher l'ensemble. Un module équivalent ne pourrait pas se faire en utilisant uniquement des fonctions, ou alors se serait ingérable et très compliqué à utiliser.

    Sinon l'exemple type qu'on voit dans les tutos est la création de personnages de jeux ou encore de paniers d'achats, enfin bref dans tous les cas on utilise des classes, c'est cela la POO. Quant à PDO - PHP Data Objects - c'est une interface qui te permet d'avoir facilement accès aux données, et l'on voit le typique "->" qui caractérise l'utilisation des classes et l'orientation objet de cette interface.

    Après MVC est encore autre chose, c'est un modèle d'architecture pour séparer les différentes couches, mais cela ne présume pas de la proportion de code procédural, de fonctions ou de classes qu'on utilise pour obtenir cette architecture. Si tu utilises un framework MVC ce sera systématiquement de la POO, mais d'un autre côté cela ne veut pas dire que tu ne pourras pas y intégrer du code procédural. Bref on peut tout mélanger, mais quelque soit l'architecture utilisée on utilise souvent une bonne proportion de classes pour faciliter la maintenance et la programmation. Cette proportion peut varier, mais si tu n'en utilise pas c'est clairement pas assez, surtout pour un projet from scratch qui ne concerne pas qu'une page de code mais tout un site.

    EDIT Pour rappel je t'ai répondu dans mon message précédent pour le htmlspecialchars et c'est important. Je te le rappelle car comme je viens d'entamer une nouvelle page tu ne le verra pas si tu ne regardes que le dernier message.

  2. #22
    Membre du Club Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Points : 64
    Points
    64
    Par défaut
    Tu as raison, il serait stupide de finir totalement un site avec ce genre de problème. Ceci-dit, je voulais surtout voir si j’étais capable de modifier ton code pour une autre page quelque peu différente et j’y suis arrivée. D’ailleurs, j’en suis super fier et c’est grâce à toi !

    Lorsque j’ai vu que le problème venait de htmlspecialchars() et qu’en modifiant cette fonction avec htmlentities cela ne changeait rien, j’ai directement pensé à l’encodage de ma page HTML, car je n’avais pas défini l’encodage de la page. En voyant que cela ne changeait pas le problème, j’ai changé l’encodage de ma page directement avec Ultra-Edit, mais là aussi, rien n’a changé. Pour ma base de donnée, je l’avais déjà modifié à utf8mb4_unicode_ci, il y a quelques jours.

    Vu que je venais de commencé un nouveau projet pour la partie ADMIN, j’ai pensé plus judicieux d’en créer un nouveau et j’ai configuré Ultra-Edit pour que chaque nouveau fichier soit en UTF-8 et que si j’ouvre un fichier qui n’a pas cet encodage, me prévenir afin que je puisse le modifier.

    Donc, mes fichiers sont tous avec l’encodage UTF-8, et la fonction htmlspecialchars() fonctionne à merveille. Ceci-dit, maintenant, je me retrouve avec de gros problèmes d’affichage. J’ai par exemple un espace sur le haut de ma page qui est impossible à supprimé. J’ai tout essayé ! Modifier le CSS, réécrire les lignes de codes PHP, HTML, CSS, modifier l’encodage du ficher CSS… Bref, quoi que je fasse, j’ai toujours cet espace sur le haut de ma page. Avec toutes ces recherches, je me suis rendue compte que cet espace vient à cause des fichiers que j’inclus :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     //	Inclusions des fichiers principaux
    define('INCLUDES_FILES',array('header'=>'header.php',
    						'footer'=>'footer.php',
    						'variables'=>'variables.php',
    						'fonctions'=>'fonctions.php'
    						));
     
    foreach(INCLUDES_FILES as $index => $files) {
    	if (!file_exists('includes/'.$files)) { header('Location: alerte.php?warning=500'); }
    	if (($index == 'variables') || ($index == 'fonctions')) { include('includes/'.$files); }
    }

    Donc, là je suis à bout de solution… Je ne vais pas abandonner comme ça, mais j’avoue que c’est très frustrant !

    Pour ce qui concerne les class, je vais suivre ton conseil et les utiliser. Autant faire les choses correctement et le travail ne me fait pas peur.
    • On dit que le ridicule ne tue pas; On dit aussi que ce qui nous tue pas, nous rends plus fort; Alors pourquoi ne pas dire : Le ridicule nous rends plus fort !
    • On reproche aux gens de parler d'eux-même; C'est pourtant le sujet qu'ils traitent le mieux !

  3. #23
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    je ne sais pas si tu le fais mais il est conseillé de faire un reset des css pour éviter d'avoir des mises en pages différentes suivant les navigateurs. Notamment les body et p et tout un tas d'autres balises ont des margin et padding par défaut non null et variables suivant les navigateurs, donc en haut du css on fait par exemple p {margin:0;padding:0} et ensuite si on veut des marges ou des espacements on le fait en ciblant les éléments voulus.

    Perso j'utilise ce code que j'ai trouvé sur internet :

    Code css : 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
    html, body, div, span, applet, object, iframe,
    h1, h2, h3, h4, h5, h6, p, blockquote, pre,
    a, abbr, acronym, address, big, cite, code,
    del, dfn, em, img, ins, kbd, q, s, samp,
    small, strike, tt, var,
    b, u, i, center,
    dl, dt, dd, ol, ul, li,
    fieldset, form, label, legend,
    table, caption, tbody, tfoot, thead, tr, th, td,
    article, aside, canvas, details, embed, 
    figure, figcaption, footer, header, hgroup, 
    menu, nav, output, ruby, section, summary,
    time, mark, audio, video {
    	margin: 0;
    	padding: 0;
    	border: 0;
    	font-size: 100%;
    	font: inherit;
    	vertical-align: baseline;
    }
    /* HTML5 display-role reset for older browsers */
    article, aside, details, figcaption, figure, 
    footer, header, hgroup, menu, nav, section {
    	display: block;
    }

    Je ne sais pas si c'est la meilleure façon de faire, faudrait peut-être demander au gourou des css et tu sais de qui je parle

  4. #24
    Membre du Club Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Points : 64
    Points
    64
    Par défaut
    Citation Envoyé par ABCIWEB Voir le message
    je ne sais pas si tu le fais mais il est conseillé de faire un reset des css pour éviter d'avoir des mises en pages différentes suivant les navigateurs. Notamment les body et p et tout un tas d'autres balises ont des margin et padding par défaut non null et variables suivant les navigateurs, donc en haut du css on fait par exemple p {margin:0;padding:0} et ensuite si on veut des marges ou des espacements on le fait en ciblant les éléments voulus.
    Oui, oui je le fais d'office car je préfère gérer moi-même les padding et margin
    Code CSS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    body,td,th,input,textarea,select {
    	font-family: "Verdana", sans-serif;
    	font-size: 14px;
    	color: #000000;
    }
    body {
    	background-color: #FFFFFF;
    	margin: 0px 0px 0px 0px;
    	padding: 0px 0px 0px 0px;
    }


    Citation Envoyé par ABCIWEB Voir le message
    Je ne sais pas si c'est la meilleure façon de faire, faudrait peut-être demander au gourou des css et tu sais de qui je parles
    J'ai essayé ton code CSS, mais ça n'a pas arrangé le problème...
    Je pense qu'à ce stade, j'ai meilleur temps d'aller voir le gourou
    • On dit que le ridicule ne tue pas; On dit aussi que ce qui nous tue pas, nous rends plus fort; Alors pourquoi ne pas dire : Le ridicule nous rends plus fort !
    • On reproche aux gens de parler d'eux-même; C'est pourtant le sujet qu'ils traitent le mieux !

  5. #25
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par RinaBK Voir le message
    Je pense qu'à ce stade, j'ai meilleur temps d'aller voir le gourou
    Enfin bon il y a quand même une piste puisque tu dis que le problème disparait si tu supprimes l'insertion des fichiers php. Ce ne peut pas être les fichiers des variables et des fonctions puisqu'ils sont dans le code php. C'est probablement le fichier du header. Faudrait montrer le haut du code html et le code css correspondant une fois qu'il est inséré dans ta page.

  6. #26
    Membre du Club Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Points : 64
    Points
    64
    Par défaut
    Si seulement... J'ai essayé tous les fichiers un par un pour savoir lequel posait problème et le résultat est qu'ils posent tous le même problème J'ai même vidé tous les fichiers (pour tester) mais que les fichiers soit vide ou non, j'ai toujours cet espace blanc au dessus des pages. Pour l’instant, j'ai bidouillé un peu en mettant un style à la balise de mon tableau :
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    <table border="0" width="100%" cellpadding="15" cellspacing="0" style="margin: -19px 0px 0px 0px;">
    En faisant cela, ça arrange le problème, mais bon, c'est du bidouillage en attendant de trouver ce qui cause cela.
    J'avais même supprimé tous les espaces possible dans le code des insertions PHP, j'ai même testé mon vieux gros codes, mais rien à faire.. Cet espace ne veut pas quitter la page..




    ____________________________________________________________________

    EDIT : (Je ne voulais pas flooder, donc je poursuit en ajoutant mon message suivant)

    ____________________________________________________________________

    Bon, pour ce qui est du problème de l’espace en haut des pages, j’ai ouvert un sujet dans la salle CSS.

    Maintenant, pour ce qui est de la partie administration et du codage PHP, j’ai bien lu toutes tes explications et elles me donnent vraiment envie de faire tout cela correctement. Donc, si j’ai bien compris, il serait judicieux d’utiliser des class lorsque cela est nécessaire.

    A savoir que tous les fichiers, class et fonctions réalisées pour la partie administration ne pourront pas être utilisés pour le(s) site(s) public. C’est un peu comme si la partie administration était sur un serveur, un site sur un autre serveur, un autre site encore un autre serveur, etc. Le seul lien entre eux c’est la base de données. D’ailleurs, même si c’était possible d’utiliser les class et fonctions de la partie admin, j’aimerais autant éviter.

    Comme expliqué dans un précédent message, je suis la seule ayant accès à cette partie administration et cela ne changera pas, vu qu’elle gère plusieurs sites web.

    J’ai essayé, dans un premier temps de visualiser ce dont je vais avoir besoin afin de m’imaginer les class et fonctions que je vais devoir réaliser…

    Une grande partie des pages administratives devront pouvoir être utilisées par plusieurs sites. Chaque site est enregistré dans la base de données dont son préfixe. Il me suffira de sélectionner un site pour que ces informations passent en session. Une fois que les infos du site sont passées en session, il me suffit de me diriger sur un page, par exemple les News, pour pouvoir ajouter, modifier ou supprimer les News spécifique au site sélectionné grâce au préfixe qui va simplement modifier les noms des tables.

    Donc, j’ai une page sites.php qui me permet d’enregistrer, modifier ou supprimer les infos d’un site. C’est la seule page de la partie administration qui me permettra de gérer les sites et leurs informations.

    Quant à la page index.php de la partie admin, elle me permet de sélectionner un site et d’envoyer ces informations en session. Là aussi, c’est la seule page du site qui me permettra de sélectionner un site.

    Les autres pages de la partie administration se comporteront plus ou moins de la même manière.
    - Contrôler si un site a été sélectionné depuis la page index.php
    - Une fois le site sélectionné, contrôler si une table a été créé pour ce site
    - Si la table n’existe pas, proposer de la créer
    - Si la table existe afficher les formulaires de gestion

    Par exemple, la page de gestion des News pourra gérer toutes les tables : prefixe_newsQuant à la page de gestion des tutoriels, la page pourra gérer toutes les tables : prefixe_tutosEtc.

    Il va de soi que les architectures des tables prefixe_news n’aura pas la même architecture que les tables prefixe_tutos. Ceci-dit, toutes les tables prefixe_news auront la même architecture, tout comme toutes les table prefixe_tutos qui auront aussi la même architecture.

    Prefixe => Sera changé selon le site sélectionné passé sous session

    Donc, je vais avoir besoin d’une class qui me permettra d’ajouter, modifier et supprimer les infos sur toutes les tables. Car chaque page comportera ces fonctions.

    Dans cette class, je pense aussi qu’il serait bien de mettre la fonction qui permettra de contrôler si une table existe pour un site et de la créer, si nécessaire.

    Donc, si j’ai bien compris le truc, de créer une class avec toutes ces fonctions me permettra d’appeler cette class pour avoir accès à ces fonctions.

    Après, pour la table « sites », vu que c’est qu’une seule page qui la gère, je ne sais pas si c’est quand même nécessaire d’avoir une class pour sa gestion. Si oui, il me faudra aussi une class pour la table sites.

    Il y aura bien sur la class pour la connexion à la base de donnée. Il faudra juste que je trouve un moyen pour que ma class devine si je suis en local ou sur le serveur. Comme cela, ça m’évitera de modifier à chaque fois les infos de connexion.

    Maintenant, je serais assez curieuse de savoir si mon cahier des charge tiens la route (ce n’est qu’un bref cahier) Je me dis qu’avant de commencer le codage, autant savoir ce qui m’attends.
    • On dit que le ridicule ne tue pas; On dit aussi que ce qui nous tue pas, nous rends plus fort; Alors pourquoi ne pas dire : Le ridicule nous rends plus fort !
    • On reproche aux gens de parler d'eux-même; C'est pourtant le sujet qu'ils traitent le mieux !

  7. #27
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par RinaBK Voir le message
    Il va de soi que les architectures des tables prefixe_news n’aura pas la même architecture que les tables prefixe_tutos. Ceci-dit, toutes les tables prefixe_news auront la même architecture, tout comme toutes les table prefixe_tutos qui auront aussi la même architecture.
    Ce qui semble logique c'est de faire une classe CRUD (les requêtes pour lire, écrire, supprimer, modifier) pour chaque table, donc une classe par table. A toi de voir ensuite la façon la plus pratique pour passer le préfixe, soit dans l'initialisation de ta classe, soit dans une constante. Personnellement dans ce cas, le préfixe est dans une constante et j'écris mes requêtes "SELECT ID_page FROM ".PREFIXE_TABLE."matable WHERE monchamp = ?";
    Citation Envoyé par RinaBK Voir le message
    Dans cette class, je pense aussi qu’il serait bien de mettre la fonction qui permettra de contrôler si une table existe pour un site et de la créer, si nécessaire.
    Cela dépend si tu ne te sert de cette fonction que dans cette classe ou pas. Si cette fonction de contrôle et de création doit pouvoir être appelée depuis plusieurs classes ou depuis le code procédural, il faut faire une classe distincte que tu pourras appeler depuis n'importe où (de la même manière que tu peux appeler la classe C_PDO depuis n'importe où).

    Citation Envoyé par RinaBK Voir le message
    Donc, si j’ai bien compris le truc, de créer une class avec toutes ces fonctions me permettra d’appeler cette class pour avoir accès à ces fonctions.
    Dans un premier temps je te conseille de faire des classes spécifiques par exemple toutes les requêtes basiques qui concernent une table = 1 classe contenant ces requêtes pour cette table. C'est assez facile à faire et tu ne risque pas de te tromper car cela n'impacte pas ton architecture (tu pourrais la modifier tout en continuant d'utiliser ces classes).

    Ensuite, tu peux faire une classe contrôleur qui suivant les actions va appeler telle ou telle fonctionnalité et renvoyer le html souhaité. Par contre celle-ci est plus stratégique. Commences peut-être à faire du procédural et tu verras dans quelle mesure une classe te faciliteras la vie. Je veux dire qu'il faut éviter de faire une usine à gaz, si c'est pour avoir un code difficilement gérable et évolutif, c'est que ta classe veut faire trop de choses ou que ton architecture n'est pas au point. L'intérêt des classes c'est d'avoir une structure de code qui va traiter un problème sans avoir besoin de modifier son code. Cela ne veut pas dire qu'on doit pouvoir tout faire avec cette classe. Parfois oui, parfois non.

    Par exemple je propose dans ce module d'upload une interface utilisateur pour d'autres développeurs, donc pour des raisons pratiques la classe doit donner un accès simple à un maximum de fonctions, d'autant plus qu'on peut faire n'importe quoi lors d'un upload, redimensionner des images à la volée, insérer le nom des fichiers en bdd, contrôler les extensions, la taille des fichiers etc. Je ne sais pas à l'avance de quoi le développeur aura besoin ni ce qu'il va utiliser, ce qui oblige à faire de nombreuses options configurables etc. C'est très long à développer car il faut penser à tout, y compris laisser la possibilité de faire ce qui n'est pas prévu et pouvoir intégrer du code personnel qui sera pris en compte sans avoir besoin de modifier le code de la classe. Pour dire que l'on fait ce genre de classe pour créer des framework, mais pas dans un développement standard car on y passerait inutilement trop de temps.

    Dans ton cas, tu es la seule qui va utiliser ton code, tu sais à l'avance ce qu'il doit faire et tu peux le modifier directement, donc ce n'est pas utile de faire une classe compliquée qui va tout gérer. Tu as plutôt intérêt à faire des petites classes spécifiques et à les appeler suivant les besoins. N'essaies pas de faire du tout poo dans un premier temps, d'une part tu n'as pas l'expérience pour l'instant, et d'autre part ce n'est pas toujours utile/rentable.

    Avec un peu d'expérience tu seras vite en mesure de savoir quand il est préférable d'utiliser une classe. Si par exemple tu as plusieurs fonctions qui s'appellent pour réaliser une tâche, notamment si elles doivent partager des variables communes. Egalement si tu dois appeler plusieurs fois cet ensemble de fonctions pour différentes variables ou à plusieurs endroits de ton code, la logique de l'appel des fonctions entre elles est définie une seule fois dans ta classe.

    Si certaines fonctions sont communes à différentes classes, tu peux mettre ces fonctions dans une (ou plusieurs) classe distincte en utilisant des méthodes statiques (ex C_PDO) et tu les appelle depuis les autres classes. L'avantage des méthodes statiques est que tu n'as pas besoin d'instancier une classe pour les appeler, cela rend donc leur utilisation plus simple (moins verbeuse). Une autre solution pour les fonctions partagées est d'utiliser un trait (cf doc php), mais tu ne pourras appeler ses fonctions que depuis une autre classe et non pas depuis n'importe où comme les classes avec les méthodes statiques qui peuvent être invoquées également dans le code procédural.

    Ensuite il y a l'héritage, mais c'est pour des besoins plus spécifiques que tu découvriras dans des tutos. Dans le paragraphe précédent je t'ai justement indiqué la façon de partager des fonctions communes dans différentes classes sans faire un héritage fonctionnel, ce qui n'est pas la bonne philosophie, d'autant plus qu'on ne peut hériter que d'une seule classe.

    Après il y aussi le côté pratique de "spl_autoload_register" qui charge les classes de manière transparente en cas besoin. Pour faire la même chose avec des fonctions il faudrait une multitude de "require" ou sinon charger tout un ensemble de fonctions dont certaines ne seront pas toujours utilisées.

    Donc voilà la POO est une boite à outil puissante, à toi de prendre ce qu'il te faut suivant tes besoins. De ce que j'ai compris les pages "administration qui se comporteront plus ou moins de la même manière" pourraient probablement faire l'objet d'une (ou plusieurs) classe, elle-même faisant appel à des classes CRUD. Mais comme déjà dit commences par les classes CRUD, elles pourront te servir dans tous les cas même si tu modifies ta stratégie par la suite. Montres nous l'essentiel de ta page quand tu auras avancé.

    Citation Envoyé par RinaBK Voir le message
    Il faudra juste que je trouve un moyen pour que ma class devine si je suis en local ou sur le serveur. Comme cela, ça m’évitera de modifier à chaque fois les infos de connexion.
    Peut-être suivant la valeur de $_SERVER['DOCUMENT_ROOT']

  8. #28
    Membre du Club Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Points : 64
    Points
    64
    Par défaut
    Vu que l’espace indésirable dans le design de la page a été réparé, que j’ai retravaillé le design le la page avec les conseils que m’a donné NoSmoking, je me suis mise à refaire la page sites.php en prenant exemple, sur Crud. C’est tout simplement génial !!! Bon maintenant, si je veux bien comprendre et bien apprendre, il faut que je me lance sur une autre page, comme par exemple la page config.php pour que tout cela rentre dans ma cervelle et y reste ! Le but étant de créer une classe et de l’utiliser correctement. Mais je suis déjà super contente d’avoir terminé la page sites.php, bien que tu m’as donné la majorité des codes. Ça me fait un super bon exemple pour la suite.

    En tout cas, je te remercierais jamais assez ABCIWEB






    Juste pour montrer le résultat, voici déjà mon fichier header, footer, fonctions, et la page sites :

    header.php :
    Code HTML : 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
    <div style="background-color: #000000; color: #FFFFFF; font-size:35px; padding: 15px; margin: 0px; font-variant: small-caps; ">Administrations</div>
     
    <div class="grid-container" style="padding: 0px;">
    	<div class="grid-item" style="background-color: #9F9F9F; height: 100%;">
     
     
     
    		<div align="left" class="menuT"><a href="index.php" target="_parent">Administration</a></div>
    		<div align="left" class="menu1"><a href="infoPHP.php" target="_blank">PHP Infos</a></div>
     
    		<div align="left" class="menuT"><a href="sites.php" target="_parent">Gestion des Sites</a></div>
     
     
     
    	</div>
    	<div class="grid-item">



    footer.php :
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	</div>
    </div>
     
     
    <div align="right" style="color: #CCCCCC;">Mise &agrave; jour le <?=MAJ;?>&nbsp;&nbsp;</div>


    styles.css :
    Code CSS : 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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    body,td,th,input,textarea,select {
    	font-family: "Verdana", sans-serif;
    	font-size: 14px;
    	color: #000000;
    }
     
    body {
    	background-color: #FFFFFF;
    	margin: 0px 0px 0px 0px;
    	padding: 0px 0px 0px 0px;
    }
     
     
     
    a:link, a:visited {
    	color: #000000;
    	text-decoration: none;
    }
    a:hover {
    	color: #A8022C;
    	text-decoration: none;
    }
    a:active {
    	color: #FFFF4F;
    	text-decoration: none;
    }
     
     
     
    h1 {
    	font-size: 25px;
    	text-decoration: underline;
    	margin: 15px 0px 10px 0px;
    }
     
    h2 {
    	font-size: 20px;
    	text-decoration: underline;
    	margin: 15px 0px 10px 0px;
    }
    h3 {
    	font-size: 17px;
    	text-decoration: underline;
    	margin: 15px 0px 10px 0px;
    }
     
     
     
    .error {
    	font-weight: bold;
    	color: #A8022C;
    }
    .valide {
    	font-weight: bold;
    	color: #033D21;
    }
     
     
     
    .relode:hover {
    	background-color: #CCCCCC;
    }
    .menuT {
    	font-weight: bold;
    	padding: 10px 0px 2px 0px;
    	white-space: nowrap;
    }
    .menu1 {
    	text-indent: 10px;
    	white-space: nowrap;
    }
     
     
     
    .grid-container {
    	display: grid;
    	grid-template-columns: auto auto auto;
    }
     
    .grid-item  {
    	padding: 20px;
    	font-size: 14px;
    }




    fonctions.php
    Code PHP : 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
    <?php
     
     
     
    /***************************************************************************************************
    **********				CONNEXION À LA BASE DE DONNÉES
    *********/
     
    class C_PDO {
     
    	private static $connexion;
     
    	private static function newC_PDO() {
     
    		$hostname = 'localhost';
    		$username = 'root';
    		$password = '';
    		$database = 'gwanda';
     
    		// Options de configuration PDO utilisées dans les exemples
    		$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
    		$pdo_options[PDO::ATTR_EMULATE_PREPARES] = false;
    		$pdo_options[PDO::ATTR_DEFAULT_FETCH_MODE] = PDO::FETCH_OBJ;
     
    		self::$connexion  = new PDO('mysql:host='.$hostname.';dbname='.$database.';charset=utf8', $username, $password, $pdo_options);
    	}
     
    	public static function getC() {
    		if(self::$connexion == NULL) {self::newC_PDO();}
    		return self::$connexion;
    	}	 
    }
    ?>


    index.php
    Code PHP : 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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    <?
    define('MAJ','29.01.2021 22:27:40');
     
     
     
     
    //	Initialisation des sessions
    session_start();
     
     
     
     
    //	Initialisation des variables de session pour la sélection d'un site
    if (!isSet($_SESSION['site'])) {
    	$siteID = '';
    	$sitePrefixe = '';
    	$siteName = '';
    } else {
    	$siteID = $_SESSION['site']['id'];
    	$sitePrefixe = $_SESSION['site']['prefixe'];
    	$siteName = $_SESSION['site']['nom'];
    }
    if ((isSet($_GET['id'])) && (isSet($_GET['nom'])) && (isSet($_GET['prefixe']))) {
    	$siteID = $_GET['id'];
    	$sitePrefixe = $_GET['prefixe'];
    	$siteName = $_GET['nom'];
    	$_SESSION['site']['id'] = $siteID;
    	$_SESSION['site']['prefixe'] = $sitePrefixe;
    	$_SESSION['site']['nom'] = $siteName;
    }
     
    if ((isSet($_GET['sites'])) && ($_GET['sites'] == 'stop')) {
    	$siteID = '';
    	$sitePrefixe = '';
    	$siteName = '';
    	$_SESSION['site']['id'] = '';
    	$_SESSION['site']['prefixe'] = '';
    	$_SESSION['site']['nom'] = '';
    }
     
     
     
     
     
     
    //	Inclusions des fichiers principaux
    define('INCLUDES_FILES', array(
    		'header'=>'header.php',
    		'footer'=>'footer.php',
    		'variables'=>'variables.php',
    		'fonctions'=>'fonctions.php'
    		));
     
    foreach (INCLUDES_FILES as $index => $files) {
    	if (!file_exists('includes/'.$files)) { header('Location: alerte.php?warning=500'); }
    	if ($index == 'variables' || $index == 'fonctions') { include('includes/'.$files); }
    }
     
     
     
     
     
    //	Récupérations des enregistrements de la base de données
    $sql = 'SELECT * FROM adm_sites';
    $db = C_PDO::getC();
    $read = $db->query($sql);
     
     
     
     
     
     
    ?>
    <!DOCTYPE html>
    <html lang="fr-CH">
    <head>
    	<title>Administrations</title>
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    	<meta http-equiv="cache-control" content="no-cache" />
    	<meta http-equiv="pragma" content="no-cache" />
    	<link rel="stylesheet" href="images/designs/styles.css" />
    	<script src="https://kit.fontawesome.com/2e9b34a81e.js"></script>
    </head>
     
     
    <body>
    <? include('includes/'.INCLUDES_FILES['header']); ?>
     
     
     
     
    <h1>Administrations</h1>
    <div align="justify">
    	Partie administration pour le serveur Gwanda.ch qui gère tous les sites positionnés sur ce serveur afin de les administrer. 
    	Cette page d’accueil permet de gérer un site en le sélectionnant dans la liste ci-dessous. Le site sera alors administrable 
    	sur les autres pages de cette partie administration. Il se peut que certaines pages administratives soient spécialement 
    	conçues pour un site spécifique. Il sera alors nécessaire de sélectionner le site en question pour que ces pages soient 
    	accessibles. Cette page d’accueil peut aussi me permettre de faire quelques tests d’affichage sur des petites lignes de 
    	codes. Pour de plus gros test, il sera nécessaire d’utiliser la page TEST prévue à cet effet.
    </div>
    <br />
    <br />
     
     
     
     
    <?
    // Exemple :
     
    $selectionne = empty($siteID) ? 'Expression 1' : 'Expression 2';
    echo $selectionne;
     
    ?>
     
     
     
     
    <br />
    <br />
    <h2>Sélectionner un site</h2>
    <div align="left">
    	Site actuellement sélectionné : 
    	<?php
    	if (empty($siteID)) { echo '<b>Aucun</b>'; }
    	else {
    		echo '<span style="margin: 0px 0px 0px 15px;">'.$siteID.'. <b>'.$siteName.'</b> ['.$sitePrefixe.']</span>';
    		echo '<a href="'.$_SERVER['SCRIPT_NAME'].'?sites=stop" target="_parent" style="margin: 0px 0px 0px 15px;" title="Supprimer la sélection de ce site"><i class="fas fa-trash-alt"></i></a>';
    	}
    	?>
    </div>
    <br />
     
     
     
     
     
    <?php
    foreach ($read as $row) {
    	echo '<a href="'.$_SERVER['SCRIPT_NAME'].'?id='.($row->id).'&prefixe='.($row->prefixe).'&nom='.($row->nom).'" target="_parent">'.($row->id).'. '.($row->nom).' ['.($row->prefixe).']</a><br />';
    }
    ?>
     
     
     
     
     
    <? include('includes/'.INCLUDES_FILES['footer']); ?>
    </body>
    </html>




    sites.php
    Code PHP : 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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    <?php
     
    //	Date de mise à jour de la page
    define('MAJ','30.01.2021 02:58:30');
     
     
     
     
    //	Initialisations des variables de sessions
    session_start();
     
     
     
     
    //	Contrôle des variables de session et initialisation
    if (!isset($_SESSION['site'])) {
    	$siteID = '';
    	$sitePrefixe = '';
    	$siteName = '';
    } else {
    	$siteID = $_SESSION['site']['id'];
    	$sitePrefixe = $_SESSION['site']['prefixe'];
    	$siteName = $_SESSION['site']['nom'];
    }
     
     
     
     
     
     
    //	Inclusions des fichiers principaux
    define('INCLUDES_FILES', array(
    		'header'=>'header.php',
    		'footer'=>'footer.php',
    		'variables'=>'variables.php',
    		'fonctions'=>'fonctions.php'
    		));
     
    foreach (INCLUDES_FILES as $index => $files) {
    	if (!file_exists('includes/'.$files)) { header('Location: alerte.php?warning=500'); }
    	if ($index == 'variables' || $index == 'fonctions') { include('includes/'.$files); }
    }
     
     
     
     
     
    /*
    CREATE TABLE adm_sites (
    	id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    	prefixe VARCHAR(200) NULL,
    	nom VARCHAR(200) NOT NULL,
    	infos TEXT NULL,
    	PRIMARY KEY (id),
    	UNIQUE (prefixe)
    );
    */
     
     
    class AdminCrud {
     
    	private $connect;
     
    	// S'exécute lorsqu'on instancie la classe
    	public function __construct($connexion) {
    		$this->connect = $connexion;
    	}
     
     
    	//	Fonction de modifications
    	public function modifier( $id, $vPrefixe, $vNom, $vInfos) {
    		try {
    			$requete = "UPDATE adm_sites SET prefixe = ?, nom = ?, infos = ? WHERE adm_sites.id = ?";
    			$stmt = $this->connect->prepare($requete);
    			$stmt->execute([$vPrefixe, $vNom, $vInfos, $id]);
    			$count = $stmt->rowCount();
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $count ? "Modification terminée" : "Impossible de modifier"; 
    	}
     
     
     
    	//	Fonction de suppression
    	public function supprimer($id) {
    		try {
    			$requete = "DELETE FROM adm_sites WHERE adm_sites.id = ?";
    			$stmt = $this->connect->prepare($requete);
    			$stmt->execute([$id]);
    			$count = $stmt->rowCount();
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $count ? "Suppression terminée" : "Impossible de supprimer";
    	}
     
     
     
    	// Fonction d'insertion
    	public function inserer($vPrefixe, $vNom, $vInfos) {
    		try {
    			$requete = "INSERT INTO adm_sites (prefixe, nom, infos) VALUES(?, ?,?)";
    			$stmt = $this->connect->prepare($requete);
    			$stmt->execute([$vPrefixe, $vNom, $vInfos]);
    			//	Trouve l'ID incrémenté
    			$id = $this->connect->lastInsertId ();
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $id;
    	}
     
     
    	// Fonction de lecture
    	public function lire () {
    		try {
    			$select = "SELECT id, prefixe, nom, infos FROM adm_sites ORDER BY id";
    			// Pas besoin de requête préparée ici puisqu'il n'y a pas de variables utilisateur dans la requête
    			$read = $this->connect->query($select);
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $read;
    	}
    }
     
     
     
     
     
     
    // Initialise la classe AdminCrud en passant la connexion en paramètre
    $crud = new AdminCrud(C_PDO::getC());
     
     
     
     
    // function de vérification commune à l'ajout et à la modification
    function verifpost ($post) {
    	$erreur = empty($post['vNom']) ? "Le nom doit être renseignée" : null;
    	$erreur = empty($post['vPrefixe']) ? "Le préfixe doit être renseignée" : $erreur;
    	return $erreur;
    }
     
     
     
     
    // Ajout en provenance du formulaire
    if (isset($_POST["ajout"]) && $_POST["ajout"] == "ajouter") {
     
    	// Enregistre le post en session pour éviter d'avoir à ressaisir tous les champs en cas d'erreur
    	$_SESSION['ajout_sites'] = $_POST;
     
    	//J'applique trim sur les éléments du tableau pour supprimer les espaces blancs en début et fin de chaine qui pourraient être rentrés inopinément par l'utilisateur
    	$post = array_map('trim',$_POST);
     
    	//Fonction de vérification
    	$erreur = verifpost($post);
     
    	// Si pas d'erreur on lance l'insertion en récupèrant l'id auto incrémenté
    	$id = empty($erreur) ? $crud->inserer($post['vPrefixe'], $post['vNom'], $post['vInfos']) : null;
     
    	// On affiche un message d'erreur uniquement si nécéssaire. Si OK le header renverra vers l'élément inséré
    	$_SESSION['message_sites'] = isset($erreur) ? $erreur : null;
     
    	// Header pour éviter les multiples post et le messgae du navigateur si on réaffiche cette page. L'ancre id sert pour aller à l'élément inséré
    	header('Location: '.$_SERVER['PHP_SELF'].'?gestion=new#lent'.$id);exit;
    }
     
     
     
     
     
    // Modification en provenance du formulaire
    if (isset($_POST["modif"]) && $_POST["modif"] == "modifier") {
    	$_SESSION['modif_sites'] = $_POST;
    	$post = array_map('trim',$_POST);
    	$erreur = verifpost($post);
    	$_SESSION['message_sites'] = empty($erreur) ? $crud->modifier($post['id'], $post['vPrefixe'], $post['vNom'], $post['vInfos']) : $erreur;
    	header('Location: '.$_SERVER['PHP_SELF'].'#lent'.$post['id']);exit;
    }
     
     
     
     
    // Suppression en provenance du formulaire
    if (isset($_POST["suppr"]) && $_POST["suppr"] == "supprimer") {
    	$_SESSION['message_sites'] = $crud->supprimer($_POST['id']);
    	header('Location: '.$_SERVER['PHP_SELF']);exit;
    }
     
     
     
     
    // Variables qui pourront être affichées dans le html pour les ajouts, modifications et suppressions
    $message = isset($_SESSION['message_sites']) ? $_SESSION['message_sites'] : null;
     
    $modif = isset($_SESSION['modif_sites']) ? $_SESSION['modif_sites'] : null;
    // $id_modif pour cibler le formulaire de modification
    $id_modif = isset($_SESSION['modif_sites']['id']) ? $_SESSION['modif_sites']['id'] : null;
     
    // On fait également un test sur message pour ne pas remplir les champs du formulaire d'ajout si l'insertion est réussie
    $ajout = isset($message,$_SESSION['ajout_sites']) ? $_SESSION['ajout_sites'] : null;
     
    // On efface les variables de session pour qu'elles ne soient définies qu'une fois
    unset($_SESSION['message_sites'],$_SESSION['modif_sites'],$_SESSION['ajout_sites']);
     
     
     
     
    //Affichage des résultats en alimentant (hydratant) les champs des formulaires de modification et suppression
    $read = $crud->lire();
     
     
     
     
     
    ?>
    <!DOCTYPE html>
    <html lang="fr-CH">
    <head>
    	<title>Administrations</title>
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    	<meta http-equiv="cache-control" content="no-cache" />
    	<meta http-equiv="pragma" content="no-cache" />
    	<link rel="stylesheet" href="images/designs/styles.css" />
    	<script src="https://kit.fontawesome.com/2e9b34a81e.js"></script>
    	<style>
    		form p {
    			margin:0.5em;
    			padding:0;
    		}
    		form .label {
    			display:inline-block;
    			width:120px;
    		}
    		#message {
    			border:1px solid black;
    			background:#0CF;
    			font-size:1.5em;
    			text-align:center;
    		}
    		.saisie {
    			width: 400px;
    		}
    		button {
    			padding: 3px;
    			width: 100px;
    		}
    	</style>
    </head>
     
     
     
    <body>
    <? include('includes/'.INCLUDES_FILES['header']); ?>
     
     
     
     
     
    <h1>Administrations</h1>
    <div align="justify">
    	Vu que le préfixe ainsi que le nom du site peuvent être utilisés comme variables, il serait important de ne pas mettre ces 
    	deux informations avec des caractères accentués ou avec des caractères spéciaux. Ceci-dit, je peux utiliser le ‘CamelCase’ 
    	pour différencier les mots ce qui permet de laisser tout de même une facilité de lecture. Pour ce qui est du champ ‘infos’, 
    	libre à moi d’écrire librement et sans contrainte.
    </div>
    <br />
    <br />
     
     
     
     
     
    <br />
    <a href="sites.php?gestion=new" target="_parent" title="Ajouter une entr&eacute;e"><i class="fas fa-folder-plus" style="font-size: 30px;"></i></a>
    <br />
     
     
     
     
     
    <?php
    //	On fait afficher ici les messages de suppressions et d'ajouts mais pas ceux de modifications qui seront affichées dans le formulaire concerné
    if(isset($message) && empty($id_modif)) echo '<p id="message">'.htmlspecialchars($message).'</p>';
     
     
    if (!empty($_GET['gestion'])) {
    	?>
    	<br />
    	<form action="#" method="POST">
    		<fieldset style="width: 600px;">
    			<legend>Ajouter</legend>
    			<p><label><span class="label">Nom : </span><input type="text" name="vNom" value="<?=isset($ajout['vNom']) ? htmlspecialchars($ajout['vNom']) : null;?>" class="saisie" /></label></p>
    			<p><label><span class="label">Prefixe : </span><input type="text" name="vPrefixe" value="<?=isset($ajout['vPrefixe']) ? htmlspecialchars($ajout['vPrefixe']) : null;?>" class="saisie" /></label></p>
    			<p><label><span class="label">Infos : </span><textarea name="vInfos" class="saisie"><?=isset($ajout['vInfos']) ? htmlspecialchars($ajout['vInfos']) : null;?></textarea></label></p>
    			<div align="center"><button type="submit" name="ajout" value="ajouter">Ajouter</button></div>
    		</fieldset>
    	</form>
    	<br />
    	<?php
    }
    foreach ($read as $row) {
    	?>
    	<!-- L'ID sert d'ancre de redirection pour les ajouts / modifications (Attention de ne pas utiliser d'ID statique dans ces lignes puisque c'est une boucle) //-->
    	<br />
    	<form action="#" method="post" style="margin-bottom:0.5em" id="lent<?= isset($row->id)? ($row->id) : ''?>">
    		<fieldset style="width: 600px;">
    			<!-- message des modifications -->
    			<legend>Modifier/Supprimer</legend>
    			<?= isset($id_modif, $message) && $row->id == $id_modif ? '<p style="color:blue">'.htmlspecialchars($message).'<p>' : ''?>
    			<input type="hidden" name="id" value="<?= ($row->id)?>" >
    			<p><label><span class="label">Nom : </span><input type="text" name="vNom" value="<?= $row->id == $id_modif ? htmlspecialchars($modif['vNom']) : ($row->nom) ?>" class="saisie" /></label></p>
    			<p><label><span class="label">Prefixe : </span><input type="text" name="vPrefixe" value="<?= $row->id == $id_modif ? htmlspecialchars($modif['vPrefixe']) : ($row->prefixe) ?>" class="saisie" /></label></p>
    			<p><label><span class="label">Infos : </span><textarea name="vInfos" class="saisie"><?= $row->id == $id_modif ? htmlspecialchars($modif['vInfos']) : ($row->infos) ?></textarea></label></p>
    			<div align="center">
    				<button type="submit" name="modif" value="modifier">Modifier</button>
    				<button type="submit" name="suppr" value="supprimer" style="margin-left:2em">Supprimer</button>
    			</div>
    		</fieldset>
    	</form>
    	<?php
    }
    ?>
     
     
     
     
    <? include('includes/'.INCLUDES_FILES['footer']); ?>
    </body>
    </html>


    Pour l'instent, je n'ai pas séparé la class AdminCrud de la page. Je le ferais seulement si j'ai besoin de cette class dans une autre page du site admin
    • On dit que le ridicule ne tue pas; On dit aussi que ce qui nous tue pas, nous rends plus fort; Alors pourquoi ne pas dire : Le ridicule nous rends plus fort !
    • On reproche aux gens de parler d'eux-même; C'est pourtant le sujet qu'ils traitent le mieux !

  9. #29
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Oui ça commence à être simple à lire et à comprendre. Niveau html/css si ça passe dans le validateur du w3c c'est ok. Juste pas la peine de faire padding :0px 0px 0px 0px, padding:0 (sans unité) ça suffit pour dire que toutes les valeurs sont à 0.

    Pour le code php

    - Tu as encore des isSet pas beaux.

    - Je m'étonne un peu qu'une classe soit dans un fichier nommé fonctions. Pourquoi tu n'utilises pas spl_auto_register pour charger cette classe depuis un fichier que tu mettrais dans un dossier nommé "Classes". Elle serait en bonne compagnie avec l'autre fichier "AdminCrud" qui y serait tout aussi bien. D'ailleurs tu pourrais aussi te servir de "AdminCrud" pour la requête de lecture de ton fichier "index.php", tu profiterais au passage de la gestion des exceptions de la fonction "lire()" que tu n'as pas mise en place dans le fichier index.php. La fonction spl_auto_register est hyper optimisée par php, pas la peine de s'en priver.

    L'intérêt est d'avoir un code php en haut de page qui ne contient principalement que des contrôles et des fonctions nécessaires à l'affichage. Et mettant tes requêtes dans des fichiers spécifiques tu sais où regarder si tu devais changer la structure de tes tables sans avoir besoin de chercher ailleurs. Généralement, le temps du développement, on fait souvent les requêtes dans le fichier concerné pour mieux comprendre comment les faire et une fois validées on les déporte dans un dossier de classes, pour pouvoir mieux se concentrer sur le reste du code, tout en gagnant en organisation si l'on devait modifier des tables et des requêtes. Bien sûr c'est un principe qu'on ne respecte pas toujours, mais bon... et cela permet de se rapprocher de l'organisation du modèle MVC

    Et dans ton fichier fonctions je ne mettrais que des fonctions.

    - D'ailleurs tu pourrais aussi faire un fichier distinct nommé "includes_files.php" pour inclure le bloc de code "Inclusions des fichiers principaux" que je vois redondant dans tes deux fichiers. Tu pourrais faire ensuite require ("includes_files.php"); Tout ça dans l'idée de factoriser et de simplifier ton code, à toi de voir (mais ne t'en fais pas pour les accès disques des require/includes et spl_auto_register, les serveurs c'est spécialement prévu pour servir des fichiers, en plus ils ont maintenant tous des sdd et des systèmes de cache perfectionnés, bref ce n'est pas le sujet).

  10. #30
    Membre du Club Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Points : 64
    Points
    64
    Par défaut
    Citation Envoyé par ABCIWEB Voir le message
    Oui ça commence à être simple à lire et à comprendre. Niveau html/css si ça passe dans le validateur du w3c c'est ok. Juste pas la peine de faire padding :0px 0px 0px 0px, padding:0 (sans unité) ça suffit pour dire que toutes les dimensions sont à 0.
    Oui, oui, je le sais C’est une vieille habitude et je me dis toujours que si je veux modifier plus tard le padding ou le margin, je n’ai pas besoin de tout écrire, j’ai juste qu’à changer le 0px. Mais l’un n’empêche pas l’autre, c’est clair. J’ai pas mal d’habitude que je vais devoir changer..


    Citation Envoyé par ABCIWEB Voir le message
    - Tu as encore des isSet pas beaux.
    Ah oui, juste ! Je les avais modifié, mais vu que j’ai dû refaire la page, j’ai bêtement copier/coller d’une vielle page sans prendre la peine de contrôler le code… Et visuellement, je suis encore trop habituée au langage CamelCase. Va vraiment falloir que je fasse un peu plus attention !


    Citation Envoyé par ABCIWEB Voir le message
    - Je m'étonne un peu qu'une classe soit dans un fichier nommé fonctions. Pourquoi tu n'utilises pas spl_auto_register pour charger cette classe depuis un fichier que tu mettrais dans un dossier nommé "Classes". Elle serait en bonne compagnie avec l'autre fichier "AdminCrud" qui y serait tout aussi bien. D'ailleurs tu pourrais aussi te servir de "AdminCrud" pour la requête de lecture de ton fichier "index.php", tu profiterais au passage de la gestion des exceptions de la fonction "lire()" que tu n'as pas mise en place dans le fichier index.php. La fonction spl_auto_register est hyper optimisée par php, pas la peine de s'en priver.
    Je ne vais pas laisser les classes dans le fichier fonctions.php, je voulais surtout dans un premier temps me mettre au clair sur le point codage. Clair que cela ne m’empêche pas de placer tout de suite mes codes dans les bons fichiers ! Mais j’avais dans l’idée de déjà me familiariser avec les exemples que tu m’as donnés et essayer d’en faire quelque chose.

    Cette nuit, j’ai justement pensé à la fonction lire() du fichier index.php, c’est pour cela que je n’ai pas touché à ce que j’avais fait pour la lecture des données. Je voulais surtout m’occuper de bien coder les classes et faire en sorte qu’elles fonctionnent parfaitement. Mais c’est ce que j’ai prévu pour aujourd’hui ^^ Je vais ranger correctement toutes ces classes et revoir mes lignes de codes pour qu’elles soient parfaites.

    Ceci-dit, à l’époque j’avais fait un rangement un peu comme celui que tu me proposes avec les classes, de les placer toutes dans un dossier. La différence est que mon dossier s’appelait ‘Scripts’ et j’y avais placé différents scripts ou plutôt codes PHP que j’intégrais dans différentes pages selon les besoin. L’idée en elle-même était intéressante et très pratique au départ, mais je me suis vite rendue compte que pour finir, lorsque j’avais des mises à jours cela devenait vite le bordel et je ne me retrouvais plus… J’ai donc laissé tomber cette méthode et j’ai préféré mettre chaque code directement dans les pages concernés. Si je travaillerais avec d’autres personnes, clair que les choses serait bien différentes, car on aurait un cahier des charges et on noterait chaque choses pour que tout le monde puisse s’y retrouver. Dans mon cas, je suis la seule qui programme et qui touche au code des pages. De plus, je suis continuellement en train de modifier tel ou tel chose pour ajouter ou améliorer. Je me suis rendue compte qu’il était plus simple pour moi de mettre chaque code dépendant d’une page dans cette même page afin d’éviter de m’étaler et de ne plus me retrouver à la longue. C’est là où j’ai eu l’idée de créé un fichier fonctions.php qui me permettait d’y placer des fonctions globales tel que par exemple la connexion à la base de donnée ou encore la fonction qui va chercher les variables de configurations, bref, des fonctions que j’intègre régulièrement dans mes pages. Je sais très bien que ce n’est pas correct, ni juste d’un point de vue architecture des codes de mettre tout le code (class, fonctions, etc) dans le corps d’une page et que l’on doit les séparer. D’ailleurs je voulais tellement faire correctement les choses à l’époque que j’avais commencé à faire mes sites sous templates. Mais voilà, quand on code seule comme moi et que personne d’autres ne reprendra mes codes plus tard, j’ai préféré opter pour une méthode qui me facilite le travail et qui n’encombre pas mes dossiers de fichiers qui m’oblige à passer plus de temps à m’y retrouver qu’à coder… Il va de soi que si un jour je dois faire un site pour une tierce personne, les choses seront clairement différente. Mais pour l’instant, ce jour n’est pas encore arrivé. Tout ça pour dire que tu as totalement raison de me motiver à créer un dossier pour mes classes, car effectivement c’est comme cela qu’on doit le faire. Mais je t’avouerais que je préfèrerais pour ma situation de simplement avoir un fichier classes.php où j’y placerais toutes mes classes générales. Et que pour les classes spécifiques à un fichier, de placer les classe directement dans ce fichier. Au moins de cette manière, je sais que je m’y retrouverais plus facilement. Maintenant, si je veux faire par exemple un ‘Script’ à télécharger un peu comme celui que tu as fait (Upload-Ajax), je prendrais soins de faire les choses correctement. Mais pour mon site, je préfère éviter de trop séparer et d’avoir trop de fichiers différents.


    Citation Envoyé par ABCIWEB Voir le message
    - D'ailleurs tu pourrais aussi faire un fichier distinct nommé "includes_files.php" pour inclure le bloc de code "Inclusions des fichiers principaux" que je vois redondant dans tes deux fichiers. Tu pourrais faire ensuite require ("includes_files.php"); Tout ça dans l'idée de factoriser et de simplifier ton code, à toi de voir (mais ne t'en fais pas pour les accès disques des require/includes et spl_auto_register, les serveurs c'est spécialement prévu pour servir des fichiers, en plus ils ont maintenant tous des sdd et des systèmes de cache perfectionnés, bref ce n'est pas le sujet).
    C’est ce que j’avais fait à l’époque. Mais le problème est que sur certaines pages, j’inclus d’autres fichiers spécifiques à la page en cours. Donc, de laisser la possibilité d’ajouter des fichiers supplémentaires dans chaque page, c’était plus pratique. Et vu que c’est un code qui ne change pas, qui ne prends pas beaucoup de place, autant le laisser. Mais il est clair que si j’avais 36 fichiers à inclure, j’opterais pour un fichier includes_files.php


    Là, je suis en train de travailler sur la classe qui va me permettre de contrôler si une table existe et de la créer si demandé. Ensuite, je vais l’intégrer correctement dans la page config.php et finir de corriger les fichiers, les mettre en place et tout et tout. J’ai encore la préparation d’une autre classe à faire pour le fichier config qui me permettra d’intégrer les variables de configurations dans les pages. Bref, j’ai un sacré programme pour aujourd’hui !
    • On dit que le ridicule ne tue pas; On dit aussi que ce qui nous tue pas, nous rends plus fort; Alors pourquoi ne pas dire : Le ridicule nous rends plus fort !
    • On reproche aux gens de parler d'eux-même; C'est pourtant le sujet qu'ils traitent le mieux !

  11. #31
    Membre du Club Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Points : 64
    Points
    64
    Par défaut
    Voilà, j'ai corrigé 2 ou 3 trucs sur les pages index.php, sites.php et j'ai terminé la page config.php. J'ai aussi créé un nouveau fichier que j'ai nommé classes.php que j'ai intégré dans les pages. J'ai terminé ma nouvelle classe pour la création et le contrôle d'une table, et j'en ai profité aussi pour modifier quelques noms de classes et fonctions pour mieux m'y retrouver plus tard. Bref, je pense avoir bien travaillé et pour l'instant tout fonctionne très bien.

    Dans ma page classes.php, j'ai placé la classe pour la conneion à la BDD, la classe Crud (mais j'ai modifier son nom) et la classe pour le contrôle et la création d'une table.
    Code PHP : 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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    <?php
     
    /***************************************************************************************************
    **********				CONNEXION À LA BASE DE DONNÉES
    *********/
     
    class C_PDO {
     
    	private static $connexion;
     
    	private static function newC_PDO() {
     
    		$hostname = 'localhost';
    		$username = 'root';
    		$password = '';
    		$database = 'gwanda';
     
    		// Options de configuration PDO utilisées dans les exemples
    		$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
    		$pdo_options[PDO::ATTR_EMULATE_PREPARES] = false;
    		$pdo_options[PDO::ATTR_DEFAULT_FETCH_MODE] = PDO::FETCH_OBJ;
     
    		self::$connexion  = new PDO('mysql:host='.$hostname.';dbname='.$database.';charset=utf8', $username, $password, $pdo_options);
    	}
     
    	public static function getC() {
    		if(self::$connexion == NULL) {self::newC_PDO();}
    		return self::$connexion;
    	}	 
    }
     
     
     
     
     
    /***************************************************************************************************
    **********				CLASSE DE CONTROLE & CREATION D'UNE TABLE
    *********/
     
    class GestionTable {
     
    	private $connect;
     
    	// S'exécute lorsqu'on instancie la classe
    	public function __construct($connexion) {
    		$this->connect = $connexion;
    	}
     
    	//	Fonction contrôle si la table existe
    	public function tableExists($table) {
    		try {
    			$read = $this->connect->query("SELECT 1 FROM $table LIMIT 1");
    		}
    		catch(PDOException $e) {
    			return FALSE;
    		}
    		return $read !== FALSE;
    	}
     
    	//	Fonction de création de la table
    	public function creationtable($table,$requete) {
    		try {
    			$requete = 'CREATE TABLE '.$table.' '.$requete.');';
    			$stmt = $this->connect->exec($requete);
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $stmt ? "Cr&eacute;ation de la table termin&eacute;" : "Impossible de cr&eacute;er la table";
    	}
    }
     
     
     
     
     
    /***************************************************************************************************
    **********				CLASSES DES COMPOSANTS POUR LA GESTION DES SITES
    *********/
     
    class GestionSites {
     
    	private $connect;
     
    	// S'exécute lorsqu'on instancie la classe
    	public function __construct($connexion) {
    		$this->connect = $connexion;
    	}
     
    	//	Fonction de modifications
    	public function modifier( $id, $vPrefixe, $vNom, $vInfos) {
    		try {
    			$requete = "UPDATE adm_sites SET prefixe = ?, nom = ?, infos = ? WHERE adm_sites.id = ?";
    			$stmt = $this->connect->prepare($requete);
    			$stmt->execute([$vPrefixe, $vNom, $vInfos, $id]);
    			$count = $stmt->rowCount();
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $count ? "Modification terminée" : "Impossible de modifier"; 
    	}
     
    	//	Fonction de suppression
    	public function supprimer($id) {
    		try {
    			$requete = "DELETE FROM adm_sites WHERE adm_sites.id = ?";
    			$stmt = $this->connect->prepare($requete);
    			$stmt->execute([$id]);
    			$count = $stmt->rowCount();
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $count ? "Suppression terminée" : "Impossible de supprimer";
    	}
     
    	// Fonction d'insertion
    	public function inserer($vPrefixe, $vNom, $vInfos) {
    		try {
    			$requete = "INSERT INTO adm_sites (prefixe, nom, infos) VALUES(?, ?,?)";
    			$stmt = $this->connect->prepare($requete);
    			$stmt->execute([$vPrefixe, $vNom, $vInfos]);
    			//	Trouve l'ID incrémenté
    			$id = $this->connect->lastInsertId ();
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $id;
    	}
     
    	// Fonction de lecture
    	public function lire () {
    		try {
    			$select = "SELECT id, prefixe, nom, infos FROM adm_sites ORDER BY id";
    			// Pas besoin de requête préparée ici puisqu'il n'y a pas de variables utilisateur dans la requête
    			$read = $this->connect->query($select);
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $read;
    	}
    }
    ?>

    Ensuite, voici le contenu de la page config.php
    Code PHP : 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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    <?php
    //	Date de mise à jour de la page
    define('MAJ','31.01.2021 04:39:56');
     
     
     
     
    //	Initialisations des variables de sessions
    session_start();
     
     
     
     
    //	Contrôle des variables de session et initialisation
    if (!isset($_SESSION['site'])) {
    	$siteID = '';
    	$sitePrefixe = '';
    	$siteName = '';
    } else {
    	$siteID = $_SESSION['site']['id'];
    	$sitePrefixe = $_SESSION['site']['prefixe'];
    	$siteName = $_SESSION['site']['nom'];
    }
     
     
     
     
    //	Initialisation de la constente portant le nom des table de la base de données
    define('TABLE_NAME',$sitePrefixe.'_config');
     
     
     
     
     
    //	Inclusions des fichiers principaux
    define('INCLUDES_FILES', array('header'=>'header.php','footer'=>'footer.php','variables'=>'variables.php','fonctions'=>'fonctions.php','classes'=>'classes.php'));
    foreach (INCLUDES_FILES as $index => $files) {
    	if (!file_exists('includes/'.$files)) { header('Location: alerte.php?warning=500'); }
    	if ($index == 'variables' || $index == 'fonctions' || $index == 'classes') { include('includes/'.$files); }
    }
     
     
     
     
     
    /*
    CREATE TABLE XXX_config (
    	nom VARCHAR (50) NOT NULL,
    	valeur TEXT NULL,
    	infos TEXT NULL,
    	UNIQUE (nom)
    );
    */
     
     
    class GestionConfig {
     
    	private $connect;
     
    	// S'exécute lorsqu'on instancie la classe
    	public function __construct($connexion) {
    		$this->connect = $connexion;
    	}
     
    	//	Fonction de modifications
    	public function modifier($vNom, $vValeur, $vInfos) {
    		try {
    			$requete = 'UPDATE '.TABLE_NAME.' SET nom = ?, valeur = ?, infos = ? WHERE '.TABLE_NAME.'.nom = ?';
    			$stmt = $this->connect->prepare($requete);
    			$stmt->execute([$vNom, $vValeur, $vInfos, $vNom]);
    			$count = $stmt->rowCount();
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $count ? "Modification terminée" : "Impossible de modifier"; 
    	}
     
    	//	Fonction de suppression
    	public function supprimer($nom) {
    		try {
    			$requete = 'DELETE FROM '.TABLE_NAME.' WHERE '.TABLE_NAME.'.nom = ?';
    			$stmt = $this->connect->prepare($requete);
    			$stmt->execute([$nom]);
    			$count = $stmt->rowCount();
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $count ? "Suppression terminée" : "Impossible de supprimer";
    	}
     
    	// Fonction d'insertion
    	public function inserer($vNom, $vValeur, $vInfos) {
    		try {
    			$requete = 'INSERT INTO '.TABLE_NAME.' (nom, valeur, infos) VALUES(?, ?,?)';
    			$stmt = $this->connect->prepare($requete);
    			$stmt->execute([$vNom, $vValeur, $vInfos]);
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $stmt ? $vNom : "Impossible d'enregistrer";
    	}
     
    	// Fonction de lecture
    	public function lire () {
    		try {
    			$select = 'SELECT nom, valeur, infos FROM '.TABLE_NAME.' ORDER BY nom';
    			$read = $this->connect->query($select);
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $read;
    	}
    }
     
     
     
     
     
    // Initialise des classe utilisées sur la page
    $gestClass = new GestionConfig(C_PDO::getC());
    $gestTable = new GestionTable(C_PDO::getC());
     
     
     
     
    //	Contrôle si la table utilisée existe
    $tblExist = $gestTable->tableExists(TABLE_NAME) ? TRUE : FALSE;
    $requete = '(nom VARCHAR (50) NOT NULL,valeur TEXT NULL,infos TEXT NULL,UNIQUE (nom)';
     
    //	Création de la table, si accepté
    if (isset($_POST["configdb"]) && $_POST["configdb"] == "oui") {
    	$erreur = $gestTable->creationtable(TABLE_NAME,$requete);
    	header('Location: '.$_SERVER['PHP_SELF']);exit;
    }
     
     
     
     
    // function de vérification commune à l'ajout et à la modification
    function verifpost ($post) {
    	$erreur = empty($post['vValeur']) ? "Le valeur doit être renseignée" : null;
    	$erreur = empty($post['vNom']) ? "Le préfixe doit être renseignée" : $erreur;
    	return $erreur;
    }
     
     
     
    // Ajout en provenance du formulaire
    if (isset($_POST["ajout"]) && $_POST["ajout"] == "ajouter") {
     
    	// Enregistre le post en session pour éviter d'avoir à ressaisir tous les champs en cas d'erreur
    	$_SESSION['msg_ajout'] = $_POST;
     
    	//J'applique trim sur les éléments du tableau pour supprimer les espaces blancs en début et fin de chaine qui pourraient être rentrés inopinément par l'utilisateur
    	$post = array_map('trim',$_POST);
     
    	//Fonction de vérification
    	$erreur = verifpost($post);
     
    	// Si pas d'erreur on lance l'insertion en récupèrant l'id auto incrémenté
    	$nom = empty($erreur) ? $gestClass->inserer($post['vNom'], $post['vValeur'], $post['vInfos']) : null;
     
    	// On affiche un message d'erreur uniquement si nécéssaire. Si OK le header renverra vers l'élément inséré
    	$_SESSION['msg_global'] = isset($erreur) ? $erreur : null;
     
    	// Header pour éviter les multiples post et le messgae du navigateur si on réaffiche cette page. L'ancre id sert pour aller à l'élément inséré
    	header('Location: '.$_SERVER['PHP_SELF'].'?gestion=new#lent'.$nom);exit;
    }
     
     
     
     
    // Modification en provenance du formulaire
    if (isset($_POST["modif"]) && $_POST["modif"] == "modifier") {
    	$_SESSION['msg_modifier'] = $_POST;
    	$post = array_map('trim',$_POST);
    	$erreur = verifpost($post);
    	$_SESSION['msg_global'] = empty($erreur) ? $gestClass->modifier($post['vNom'], $post['vValeur'], $post['vInfos']) : $erreur;
    	header('Location: '.$_SERVER['PHP_SELF'].'#lent'.$post['vNom']);exit;
    }
     
     
     
    // Suppression en provenance du formulaire
    if (isset($_POST["suppr"]) && $_POST["suppr"] == "supprimer") {
    	$_SESSION['msg_global'] = $gestClass->supprimer($_POST['nom']);
    	header('Location: '.$_SERVER['PHP_SELF']);exit;
    }
     
     
     
     
    // Variables qui pourront être affichées dans le html pour les ajouts, modifications et suppressions
    $message = isset($_SESSION['msg_global']) ? $_SESSION['msg_global'] : null;
     
    $modif = isset($_SESSION['msg_modifier']) ? $_SESSION['msg_modifier'] : null;
    // $id_modif pour cibler le formulaire de modification
    $id_modif = isset($_SESSION['msg_modifier']['nom']) ? $_SESSION['msg_modifier']['nom'] : null;
     
    // On fait également un test sur message pour ne pas remplir les champs du formulaire d'ajout si l'insertion est réussie
    $ajout = isset($message,$_SESSION['msg_ajout']) ? $_SESSION['msg_ajout'] : null;
     
    // On efface les variables de session pour qu'elles ne soient définies qu'une fois
    unset($_SESSION['msg_global'],$_SESSION['msg_modifier'],$_SESSION['msg_ajout']);
     
     
     
     
     
    //Affichage des résultats en alimentant (hydratant) les champs des formulaires de modification et suppression
    if (($siteID != '') && ($sitePrefixe != '') && ($siteName != '') && ($tblExist == TRUE)) {
    	$read = $gestClass->lire();
    }
     
     
     
     
    ?>
    <!DOCTYPE html>
    <html lang="fr-CH">
    <head>
    	<title>Administrations</title>
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    	<meta http-equiv="cache-control" content="no-cache" />
    	<meta http-equiv="pragma" content="no-cache" />
    	<link rel="stylesheet" href="images/designs/styles.css" />
    	<script src="https://kit.fontawesome.com/2e9b34a81e.js"></script>
    	<style>
    		form p {
    			margin:0.5em;
    			padding:0;
    		}
    		form .label {
    			display:inline-block;
    			width:120px;
    		}
    		#message {
    			border:1px solid black;
    			background:#FFFFB0;
    			font-size:1.5em;
    			text-align:center;
    		}
    		.saisie {
    			width: 400px;
    		}
    		button {
    			padding: 3px;
    			width: 100px;
    		}
    	</style>
    </head>
     
     
     
    <body>
    <? include('includes/'.INCLUDES_FILES['header']); ?>
     
     
     
    <h1>Configurations</h1>
    <div align="justify">
    	La configuration permet d’enregistrer certaines variables ou plutôt certaines constantes qui permettent de spécifier certaines 
    	configurations sur les pages du site. Elles permettent d’apporter d’une manière simple des constantes et de pouvoir modifier 
    	leur valeur facilement depuis les formulaires ci-dessous. Il suffira de s’orienter par rapport au nom de la constante et les 
    	informations qu’elles disposent et de modifier sa valeur. Pour l’ajout de nouvelles consentes, il serait important d’utiliser le 
    	CamelCase et de bien contrôler que le nom de la consentes soit unique afin d’éviter des problèmes de compatibilité. 
    </div>
    <br />
    <br />
     
     
     
    <?
    //	Contrôle si un site a été préalablement sélectionné, sinon : message d'alerte
    if (($siteID == '') || ($sitePrefixe == '') || ($siteName == '')) {
    	echo '<a href="index.php" target="_parent"><span class="error"><i class="fas fa-exclamation-triangle"></i>&nbsp;<b>Veuillez s&eacute;lectionner le site&nbsp;<i class="fas fa-exclamation-triangle"></i></b></span></a><br />';
    } else {
    	echo 'Site actuellement s&eacute;lectionn&eacute;&nbsp;:&nbsp;&nbsp;&nbsp;<b>'.$siteID.'.&nbsp;'.$siteName.'&nbsp;&nbsp;['.$sitePrefixe.']</b>';
    	echo '&nbsp;&nbsp;&nbsp;<a href="index.php" target="_parent" title="Changer de site actif"><i class="fas fa-exchange-alt"></i></a><br />';
     
    	//	Si la table n'existe pas, demander si la créer
    	if ($tblExist == FALSE) {
    		?>
    		<br />
    		<div align="left" class="error">
    			<i class="fas fa-exclamation-triangle"></i>&nbsp;<u>Aucune base de donn&eacute;es disponible pour ce site&nbsp;!</u>&nbsp;<i class="fas fa-exclamation-triangle"></i>
    		</div>
    		<br />
    		<div align="left" style="padding: 10px 0px 10px 0px;">Voulez-vous cr&eacute;er un table pour le site &quot;<b><?=$siteName;?></b>&quot;&nbsp;?<br /></div>
    		<form method="POST">
    			<button type="submit" name="configdb" value="oui">Oui</button>
    			<button type="reset" name="" value="non" onclick="location.href='index.php'">Non</button>
    		</form>
    		<?
    	}
    }
     
     
     
     
     
    //	On fait afficher ici les messages de suppressions et d'ajouts mais pas ceux de modifications qui seront affichées dans le formulaire concerné
    if(isset($message) && empty($id_modif)) echo '<p id="message">'.htmlspecialchars($message).'</p>';
     
     
    if (($siteID != '') && ($sitePrefixe != '') && ($siteName != '') && ($tblExist == TRUE)) {
     
    	?>
    	<br />
    	<a href="<?=$_SERVER['PHP_SELF'];?>?gestion=new" target="_parent" title="Ajouter une entr&eacute;e"><i class="fas fa-folder-plus" style="font-size: 30px;"></i></a>
    	<br />
    	<?
     
    	if (!empty($_GET['gestion'])) {
    		?>
    		<br />
    		<form action="#" method="POST">
    			<fieldset style="width: 600px;">
    				<legend>Ajouter</legend>
    				<p><label><span class="label">nom : </span><input type="text" name="vNom" value="<?=isset($ajout['vNom']) ? htmlspecialchars($ajout['vNom']) : null;?>" class="saisie" /></label></p>
    				<p><label><span class="label">valeur : </span><input type="text" name="vValeur" value="<?=isset($ajout['vValeur']) ? htmlspecialchars($ajout['vValeur']) : null;?>" class="saisie" /></label></p>
    				<p><label><span class="label">Infos : </span><textarea name="vInfos" class="saisie"><?=isset($ajout['vInfos']) ? htmlspecialchars($ajout['vInfos']) : null;?></textarea></label></p>
    				<div align="center"><button type="submit" name="ajout" value="ajouter">Ajouter</button></div>
    			</fieldset>
    		</form>
    		<br />
    		<?php
    	}
     
     
     
     
    	foreach ($read as $row) {
    		?>
    		<!-- L'ID sert d'ancre de redirection pour les ajouts / modifications (Attention de ne pas utiliser d'ID statique dans ces lignes puisque c'est une boucle) //-->
    		<br />
    		<form action="#" method="post" style="margin-bottom:0.5em" id="lent<?= isset($row->nom)? ($row->nom) : ''?>">
    			<fieldset style="width: 600px;">
    				<!-- message des modifications -->
    				<legend>Modifier/Supprimer</legend>
    				<?= isset($id_modif, $message) && $row->nom == $id_modif ? '<p style="color:blue">'.htmlspecialchars($message).'<p>' : ''?>
    				<input type="hidden" name="id" value="<?= ($row->nom)?>" >
    				<p><label><span class="label">nom : </span><input type="text" name="vNom"readonly  value="<?= $row->nom == $id_modif ? htmlspecialchars($modif['vNom']) : ($row->nom) ?>" class="saisie" /></label></p>
    				<p><label><span class="label">valeur : </span><input type="text" name="vValeur" value="<?= $row->nom == $id_modif ? htmlspecialchars($modif['vValeur']) : ($row->valeur) ?>" class="saisie" /></label></p>
    				<p><label><span class="label">Infos : </span><textarea name="vInfos" class="saisie"><?= $row->nom == $id_modif ? htmlspecialchars($modif['vInfos']) : ($row->infos) ?></textarea></label></p>
    				<div align="center">
    					<button type="submit" name="modif" value="modifier">Modifier</button>
    					<button type="submit" name="suppr" value="supprimer" style="margin-left:2em">Supprimer</button>
    				</div>
    			</fieldset>
    		</form>
    		<?php
    	}
    }
    ?>
     
     
     
    <? include('includes/'.INCLUDES_FILES['footer']); ?>
    </body>
    </html>

    Je vais commencer à réaliser la page des news.php en utilisant ce même procédé. Et essayer d'avancer et pourquoi pas finir la partie admin. Je suis très impatiente de commencer les pages du site (gwanda.ch) parce que je sais que là je vais pouvoir travailler un peu plus avec les classes et je vais être confronté à d'autres constructions, tel que les tutoriels, messagerie et partie membres. Je pense que c'est à ce moment là que je vais vraiment pouvoir me tester sur les classes.
    • On dit que le ridicule ne tue pas; On dit aussi que ce qui nous tue pas, nous rends plus fort; Alors pourquoi ne pas dire : Le ridicule nous rends plus fort !
    • On reproche aux gens de parler d'eux-même; C'est pourtant le sujet qu'ils traitent le mieux !

  12. #32
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut Autoload et espaces de noms php
    Citation Envoyé par RinaBK Voir le message
    Ceci-dit, à l’époque j’avais fait un rangement un peu comme celui que tu me proposes avec les classes, de les placer toutes dans un dossier. La différence est que mon dossier s’appelait ‘Scripts’ et j’y avais placé différents scripts ou plutôt codes PHP que j’intégrais dans différentes pages selon les besoin. L’idée en elle-même était intéressante et très pratique au départ, mais je me suis vite rendue compte que pour finir, lorsque j’avais des mises à jours cela devenait vite le bordel et je ne me retrouvais plus… J’ai donc laissé tomber cette méthode et j’ai préféré mettre chaque code directement dans les pages concernés.
    Oui mais il y a moyen de s'organiser sans tout mettre dans un même dossier. L'exemple de spl_autoload_register que je t'ai donné est minimaliste (c'est celui du manuel) mais on peut faire ce que l'on veut avec cette fonction et si besoin elle peut être appelée plusieurs fois. Trivialement on peut faire :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /* Charge les classes du dossier Classes avec spl_autoload_register*/
    spl_autoload_register(function ($class) {if(is_file('Classes/' . $class . '.php')) require 'Classes/' . $class . '.php';});
    /* Charge les classes du dossier ClassesPage avec spl_autoload_register*/
    spl_autoload_register(function ($class) {if(is_file('ClassesPage/' . $class . '.php')) require 'ClassesPage/' . $class . '.php';});
     
    /*Ou encore*/
     
    spl_autoload_register(function ($class) {
        if(is_file('Classes/' . $class . '.php')) require 'Classes/' . $class . '.php';
        else
        if(is_file('ClassesPage/' . $class . '.php')) require 'ClassesPage/' . $class . '.php';
    });
    Si l'on a un ou deux répertoires de classes ça peut suffire mais on voit vite la limite, et ce n'est pas optimisé dans le sens où l'on peut avoir de nombreux "is_file" qui ne serviront à rien d'autre qu'à passer à la condition suivante si on utilise beaucoup de classes contenues dans le dossier "ClassesPage". Or la fonction "is_file" interroge le système de fichiers ce qui prend un peu de ressources, sur le principe mieux vaut éviter de les multiplier inutilement (même si pour un petit site avec peu de connexions simultanées ce sera insignifiant).

    Passons de suite au stade supérieur (c'est à peine plus compliqué), avec l'utilisation des espaces de noms et d'une classe d'autoload plus élaborée avec cet exemple. Je ne recopie ici que le code utile que j'ai légèrement modifié en créant un constructeur pour lancer automatiquement la fonction "register", tout en laissant la possibilité de l'utiliser séparément:

    class Psr4AutoloaderClass (légèrement modifiée)
    Code php : 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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    <?php
    /*
    add the path to the class files for the \Foo\Bar\ namespace prefix
     as follows:
    
       <?php
        // instantiate the loader
        $loader = new \Example\Psr4AutoloaderClass;
    
        // if $loader = new \Example\Psr4AutoloaderClass(false), register the autoloader 
        // $loader->register();
    
        // register the base directories for the namespace prefix
        $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/src');
        $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/tests');
    
    // The following line would cause the autoloader to attempt to load the
    // \Foo\Bar\Qux\Quux class from /path/to/packages/foo-bar/src/Qux/Quux.php:
    
        <?php
        new \Foo\Bar\Qux\Quux;
    
    // The following line would cause the autoloader to attempt to load the
    // \Foo\Bar\Qux\QuuxTest class from /path/to/packages/foo-bar/tests/Qux/QuuxTest.php:
    
        <?php
        new \Foo\Bar\Qux\QuuxTest;
    */
    class Psr4AutoloaderClass
    {
        protected $prefixes = array();
     
        public function __construct($register=true)
        {
    	 if(trim($register) != false) $this->register();
        }
     
        public function register()
        {
            spl_autoload_register(array($this, 'loadClass'));
        }
     
        public function addNamespace($prefix, $base_dir, $prepend = false)
        {
            $prefix = trim($prefix, '\\') . '\\';
     
            $base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . '/';
     
            if (isset($this->prefixes[$prefix]) === false) $this->prefixes[$prefix] = array();
     
            if ($prepend) array_unshift($this->prefixes[$prefix], $base_dir);
            else
            array_push($this->prefixes[$prefix], $base_dir);
        }
     
        public function loadClass($class)
        {
            $prefix = $class;
     
            while (false !== $pos = strrpos($prefix, '\\')) {
     
                $prefix = substr($class, 0, $pos + 1);
     
                $relative_class = substr($class, $pos + 1);
     
                $mapped_file = $this->loadMappedFile($prefix, $relative_class);
     
                if ($mapped_file) {return $mapped_file;}
     
                $prefix = rtrim($prefix, '\\');
            }
     
            return false;
        }
     
        protected function loadMappedFile($prefix, $relative_class)
        {
            if (isset($this->prefixes[$prefix]) === false) {
                return false;
            }
     
            foreach ($this->prefixes[$prefix] as $base_dir) {
     
                $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
     
                if ($this->requireFile($file)) {return $file;}
            }
     
            return false;
        }
     
        protected function requireFile($file)
        {
            if (file_exists($file)) {
                require $file;
                return true;
            }
            return false;
        }
    }
    ?>

    Tu peux essayer de comprendre le code en regardant les commentaires dans le lien plus haut, mais ce n'est pas nécessaire pour un usage courant et tu peux faire confiance car c'est une source directe qui provient d'un groupe de travail php.

    Les exemples ci-dessous ne suivent pas strictement la recommandation de nommage PSR4, certains sont "à l'ouest" mais je trouve cela plus éloquent pour comprendre le fonctionnement et le respect de la convention n'est pas absolument nécessaire pour un framework fait maison. Cela permet d'être moins verbeux et plus souple, mais il faut définir une convention et s'y tenir pour ne pas avoir à chercher comment écrire le code pour chaque appel à une classe. Personnellement je suis plutôt proche de cette convention, à l'exception du préfixe "vendeur" qui est inutilement contraignant pour mon utilisation.

    Avant de voir cela plus en détail, voici une méthode qui pourrait convenir à ta structure de code sans trop changer tes habitudes. Dans un fichier "ini.php" situé à la racine du serveur (répertoire www), que tu incluras dans toutes tes pages, tu pourrais mettre cette classe "Psr4AutoloaderClass" (sans l'initialiser) ainsi que certaines constantes utiles qui servent partout, et pourquoi pas quelques fonctions.

    Par exemple :

    Fichier ini.php inclus dans toutes les pages:
    Code php : 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
    /* Nom de domaine du projet*/
    define('NOM_DOMAINE', 'https://www.mlc-billom.com/');
    /* Adresse sur le serveur d'évaluation (si on utilise des alias*/
    define('LOCALHOST', 'http://mlc/');
     
    /* Base pour les url relatives dans le html (mon serveur d'évaluation est toujours situé dans un dossier "wamp64abci" à la racine d'un lecteur, ex: D:\, donc en position 3 étant donné qu'on commence à compter à 0)*/
    define('BASE_HREF', isset($_SERVER['DOCUMENT_ROOT']) && strpos($_SERVER['DOCUMENT_ROOT'],"wamp64abci") == 3 ? LOCALHOST : NOM_DOMAINE);
     
    // Base pour l'inclusion des fichiers php ainsi que footer, header,  etc.
    define('__ROOT__', __DIR__.DIRECTORY_SEPARATOR);
     
    // Css commun pour la structure
    define('CSS_COMMUN','Librairie/commun1.css'); 
     
    // En admettant que la classe Psr4AutoloaderClass se trouve dans le répertoire "Classes" à la racine du serveur :
    require __ROOT__.'Classes/Psr4AutoloaderClass.php';
    //...

    Donc une fois que ce fichier est inclus dans ta page tu peux configurer l'autoload pour charger toutes les autres classes nécessaires, et cela n'exclue pas d'avoir une classe directement dans ta page.

    En admettant que les classes communes très souvent utilisées un peu partout (comme C_PDO), se trouvent dans un dossier nommé "Classes" situé à la racine du serveur et que ma page "admin_site.php" se situe dans le dossier "Admin" situé également à la racine du serveur.

    Fichier Admin/admin_site.php
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    <?php require '../ini.php';
     
    /* instancie l'autoloader*/
    $loader = new Psr4AutoloaderClass;
     
    /* Ajoute les namespace en premier paramètre, et l'adresse en second. 
    Avec  __ROOT__ (récupéré dans ini.php) je peux  écrire tous les chemins des fichiers php par rapport à la racine du serveur (www).
    Ce chemin est donc compatible avec tous les fichiers quelque soit leur position dans les répertoires.
    */
    $loader->addNamespace('Classes', __ROOT__.'Classes');
     
    /*Si dans ce dossier "Classes" j'ai un sous répertoire nommé "Utilitaires" et que je veux pouvoir avoir accès à ses classes*/
    $loader->addNamespace('Classes\Utilitaires', __ROOT__.'Classes/Utilitaires');
     
    /*Dans mon dossier "Admin" j'ai un dossier nommé "Classes" avec des sous répertoires "modele" pour les classes de requêtes, et un autre répertoire nommé divers avec d'autres classes. 
    On voit que le namespace peut être n'importe quoi pourvu que la classe ait le même.
    */
    $loader->addNamespace('admin\modele', __ROOT__.'Admin/Classes/modele');
    $loader->addNamespace('admin\div', __ROOT__.'Admin/Classes/divers');
    $loader->addNamespace('especedeouf', __ROOT__.'Admin/Classes/divers');
     
     
    // Classe statique et appel de la méthode getC()
    $connexion = Classes\C_PDO::getC();
     
    // Autre classe instanciable située au même niveau dans le répertoire Classes que C_PDO
    $autre = new Classes\Autre;
     
     
    // Classe instanciée "Util"
    $utilitaire = new Classes\Utilitaires\Util();
     
     
    $config = new admin\modele\GestionConfig ($connexion);
     
    $diver = new admin\div\Clavier('azerty');
     
    $leouf = especedeouf\Toto::reponse();
     
    /*...*/
    ?>
    <!DOCTYPE html>
    <html lang="<?= htmlspecialchars($lang)?>">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Administrateur - Administration du contenu des Pages</title>
     
    <base href="<?=BASE_HREF?>" />
     
    <link href = "<?=CSS_COMMUN?>" rel="stylesheet"  type="text/css">
    ...
    Les classes doivent avoir le même namespace que celui déclaré dans $loader->addNamespace, qui sert également à appeler ces fonctions donc :

    Fichier Classes/C_PDO.php
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <?php
    namespace Classes;
     
    class C_PDO 
    {
    }
    ?>

    Fichier Classes/Autre.php
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <?php
    namespace Classes;
     
    class Autre 
    {
    }
    ?>

    Fichier Admin/Classes/modele/GestionConfig.php
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <?php
    namespace admin\modele;
     
    class GestionConfig
    {
     
    }
    ?>

    Fichier Admin/Classes/divers/Clavier.php
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?php
    namespace admin\div;
     
    class Clavier
    {
        public function __construct($type)
        {
     
        }
    }

    Fichier Admin/Classes/divers/Toto.php
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php
    namespace especedeouf;
     
    class Toto
    {
        static plublic function reponse()
        {
          echo "Ah c'est malin ! Obliger d'ouvrir tous les fichiers de ce répertoire pour trouver ce namespace qui ne correpond à rien pour pourvoir utiliser cette classe";
        }
    }
    ?>

    Bon j'ai fait ça sans tout contrôler, il peut y avoir des fautes mais le principe est assez simple.

    Un mot sur la constante "BASE_HREF" qui permet d'avoir toujours le même code pour inclure les fichiers CSS, javascript, images etc. quelque soit la position du fichier dans les répertoires. Et si le nom de mes fichiers CSS et Javascript sont dans une constante, c'est que j'ai installé un système de cache pour ces fichiers dans le .htacess. Donc quand je fais des changements j'enregistre le fichier dans un nouveau fichier nommé "commun2.css" par exemple et je n'ai qu'à changer cette valeur dans le fichier ini.php pour avoir une mise à jour du cache (tout en ayant une sauvegarde de mon ancien fichier css que j'efface au bout d'un moment) et idem pour mon fichier javascript.

    Bon voilà, avec ça tu pourras prendre un bon départ avec la POO car au delà de savoir comment créer des classes il faut savoir aussi comment les ranger et les appeler. Sinon tu pourrais aussi instancier et définir tous tes espaces de nom dans le fichier ini.php, puisque les classes ne sont appelées que lorsqu'elles sont invoquées dans les différents scripts. L'inconvénient est que si tu fais des espaces de nom pas tout à fait conventionnels il faudra consulter ce fichier souvent pour savoir comment appeler ces fonctions quand tu les écris, alors que c'est plus simple s'il est en haut de ta page.

    Pour suivre strictementla convention il faudrait entre autre un nom de vendeur (une base) que tu pourrais par exemple nommer "RinaCMS". Mais dans ce cas il faudrait faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $loader->addNamespace('RinaCMS\Classes', __ROOT__.'Classes');
    , et dans ton fichier C_PDO
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <?php
    namespace RinaCMS\Classes;
     
    class C_PDO 
    {
     
    }
    ?>
    Et donc pareil pour appeler ta classe il faudrait le préfixe de base: $connexion = RinaCMS\Classes\C_PDO::getC();. De même pour les autres classes, sauf pour celles qui sont dans l'espace global cf la doc php. Bref c'est un peu pénible ce préfixe "vendeur" et je n'en vois pas l'intérêt pour une utilisation personnelle. Ce qui ne veut pas dire pour autant que cela ne sert à rien dans tous les cas, on est bien d'accord.

  13. #33
    Membre du Club Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Points : 64
    Points
    64
    Par défaut
    Coucou

    Je comprends le principe, mais malgré tout, cela m’oblige à faire une multitude de fichier que je dois inclure. Après quel moyen je prends, cela m’oblige tout de même à créer des fichiers supplémentaires. Je ne critique pas le principe, mais pour une petite partie administration, au final je vais avoir beaucoup de fichier et c’est ce que j’aimerais vraiment éviter. De plus, si je reviens 6 mois plus tard pour améliorer certaines pages, je vais être complètement perdue, car je vais devoir passer en revue plusieurs fichiers pour la mise à jour d’une seule page et là, ça va être la galère ! Je serais en train de réaliser un CMS ou quelque chose du genre, oui effectivement ce principe serait très intéressant et très utile, c’est clair.

    Au total, ma partie administration comporte 15 fichiers pour 10 pages. Si je m’amusais à créer un fichier pour chaque classe, j’aurais bien plus du double de fichiers et encore… Je ne pense pas vraiment judicieux d’en faire trop pour cette partie administration. Surtout qu’en me connaissant, d’ici quelques mois, je vais très certainement la modifier voir ajouter encore des pages. Donc, si je prends le principe de créer des fichiers pour différentes choses, au final je vais me retrouver avec une 30aine de fichiers pour un site qui propose à peine 10 pages. Donc, je n’ose même pas imaginer le jour où je devrais modifier un truc, je vais prendre la journée pour quelque chose qui en temps normal me prendrais 5 minutes.

    D’ailleurs, j’avais commencé à faire un fichier par classe, et en très peu de temps, je me suis retrouvée avec le double de fichiers sur le serveur. Donc, sans même avoir fini de faire toutes les pages du site, j’avais déjà 18 fichiers pour l’affichage de 5 pages, tout en sachant que j’avais encore à réaliser 5 pages supplémentaires. Donc, au final, je me serais retrouvée avec 28 fichiers au lieu de 15.

    Ceci-dit, tu as tout à fait raison sur le principe, et je ne peux rien dire là-dessus, mis à part qu’au final, on se retrouve avec beaucoup de fichiers.


    Ce weekend, je n’ai pas chômé, car j’ai refait intégralement la partie administration. J’ai utilisé principalement 3 classes : C_PDO, GestionTable et DateExtract.

    La classe GestionTable me permet de contrôler si une table existe, la créer si nécessaire, mais aussi de lire une table ou encore de chercher des données et de les afficher par différents ordres.

    Code PHP : 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
    38
    39
    40
    41
    42
    43
    44
    class GestionTable {
     
    	private $connect;
     
    	// S'exécute lorsqu'on instancie la classe
    	public function __construct($connexion) {
    		$this->connect = $connexion;
    	}
     
    	//	Fonction contrôle si la table existe
    	public function tableExists($table) {
    		try {
    			$read = $this->connect->query("SELECT 1 FROM $table LIMIT 1");
    		}
    		catch(PDOException $e) {
    			return FALSE;
    		}
    		return $read !== FALSE;
    	}
     
    	//	Fonction de création de la table
    	public function creationTable($table,$requete) {
    		try {
    			$requete = 'CREATE TABLE '.$table.' ('.$requete.');';
    			$stmt = $this->connect->exec($requete);
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $stmt ? "Création de la table terminée" : "Impossible de créer la table";
    	}
     
    	// Fonction de lecture
    	public function lire($table,$ordre) {
    		try {
    			$select = 'SELECT * FROM '.$table.' ORDER BY '.$ordre;
    			$read = $this->connect->query($select);
    		}
    		catch(PDOException $e) {
    			exit($e->getMessage());
    		}
    		return $read;
    	}
    }

    Après, si je veux remplacer le nom de ma table $table par une requête pour chercher des données en incluant une condition, j’ai simplement qu’à modifier ma variable $table comme ceci :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $requete = TABLE_DB['MESS'].' WHERE id='.$id;
    $affiche= $gestionTable->lire($requete,$ordre);

    Ensuite, pour la classe DateExtract, j’ai placé à l’intérieur toutes mes fonctions que j’avais créées pour les conversions des dates, genre mettre le jour de la semaine en français, le mois en lettre, etc. Rien de bien particulier ou d’extraordinaire. Mais pratique quand-même.

    Ce sont les 3 classes qui se sont retrouvées dans mon fichier classes.php.
    Concernant les pages de la partie administration, je les ai toutes réalisés de la même manière. Au départ, juste après l’insertion de mes fichiers principaux, j’appelle mes classes.

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     //	Inclusions des fichiers principaux
    define('INCLUDES_FILES', array('header'=>'header.php','footer'=>'footer.php','variables'=>'variables.php','fonctions'=>'fonctions.php','classes'=>'classes.php'));
    foreach (INCLUDES_FILES as $index => $files) {
    	if (!file_exists('includes/'.$files)) { header('Location: alerte.php?warning=500'); }
    	if ($index == 'variables' || $index == 'fonctions' || $index == 'classes') { include('includes/'.$files); }
    }
     
     
    //	Appel des classes nécessaires
    $dateExtract = new DateExtract();
    $gestionTable = new GestionTable(C_PDO::getC());

    Ensuite, vu que certaines pages utilisent plusieurs tables, j’ai utilisé les constantes sous forme de tableau :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     //	Initialisations des variables utilisés
    define('TABLE_DB',array(
    			'TUTOS' => $sitePrefixe.'_tuto',
    			'CATEG' => $sitePrefixe.'_tutocat',
    			'MESS' => $sitePrefixe.'_tutomsg',
    			));

    …Et je profite par la même occasion de mettre sous constante tableaux les tables que je dois créer si nécessaire :

    Code PHP : 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
     //	Initialisations des tableaux à créer 
    define('REQUETE',array(
    	'TUTOS' => '
    		id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    		categorie BIGINT UNSIGNED NOT NULL,
    		edate TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    		page VARCHAR(200) NOT NULL,
    		titre TEXT NOT NULL,
    		PRIMARY KEY (id)
    		',
    	'CATEG' => '
    		id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    		nom VARCHAR(200) NOT NULL,
    		info TEXT NOT NULL,
    		PRIMARY KEY (id)
    		',
    	'MESS' => '
    		id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    		id_tuto BIGINT UNSIGNED NOT NULL,
    		id_mbr BIGINT UNSIGNED NOT NULL,
    		edate TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    		msg TEXT NOT NULL,
    		PRIMARY KEY (id)
    		'));

    Ensuite, j’ai plus qu’à faire une boucle pour créer mes tables, si nécessaire.
    Donc, l’avantage est que si j’ai quoi que ce soit comme problème avec mes tables ou que je dois réinstaller mon serveur et mes tables, je peux sans me préoccuper envoyer les fichiers sur le serveur et naviguer sur les pages de la partie administration pour créer les tables en cas de besoin, si elles n’existent pas. Cela m’affiche aucune erreur, mais juste un petit message qui m’informe que la table n’existe pas et qui me demande si je veux la créer. Je clique sur un bouton et hop !

    Vu que les nouveaux enregistrements, les modifications et les suppressions sont différentes à chaque page, j’ai supprimé les classes et j’ai laissé juste les fonctions : newsData(),updateData() et deleteData().

    Vu que je suis la seule à utiliser ces pages, j’ai viré les codes de contrôle sur les champs et j’ai modifié les balises pour y ajouter required ou encore pattern. Je me suis dit que se sera plus simple et quelques lignes de code en moins.

    Bref, avec tout ce que je connaissais déjà et tout ce que tu m’as appris, je dois avouer que maintenant mes pages sont vraiment superbe ! Bon, j’imagine que tu aurais pas mal de choses à redire, et c’est normal. Mais pour cette petite partie administration, je suis assez contente du résultat.

    J’ai passé tout mon weekend et le lundi compris à refaire ma partie administration et elle est terminée, fonctionne parfaitement et très agréable à utiliser. Et je peux te remercier grandement, car sans ton aide et tes conseils, j’avoue que mes lignes de codes n’auraient pas une aussi bonne allure !

    J’ai tout de même pris mardi comme journée de congé. Me suis mise sur Netflix et j’ai regardé des documentaire toute la journée et une bonne partie de la nuit. Maintenant, que je me suis bien instruit sur l’espace et ces planètes, je peux me remettre au travail et j’ai déjà un peu avancé.

    J’ai viré de mon serveur le site que j’étais en train de faire… J’ai laissé le fichier alerte.php et j’ai modifié mon fichier .htaccess :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     RewriteEngine on
    RewriteRule ^/?$ https://www.gwanda.ch/alerte.php
    Comme cela, si une personne entre l’adresse de mon site, elle sera redirigée sur mon petit message de maintenance. Aussi, ça me laisse de garder mon fichier index.php accessible pour commencer les travaux. Là, je suis en train de refaire le design et la partie HTML de base. Rien de bien extraordinaire pour l’instant. Mais une fois que j’aurais terminé, je vais avoir un sacré boulot, car je vais refaire la totalité des codes PHP et tout revoir. Étant donné que ce sera un site ‘public’ je serais obligée de faire attention à la stupidité des utilisateurs, car nous le savons tous, certains utilisateurs ne sont pas du tout doué en informatique et je sais de quoi je parle ! Quand je dis à mon papa ou ma maman : Ton navigateur est ouvert ? ...Et qu’ils me répondent : Non, je suis sur Facebook ou Google… Bref, j’en rigole toujours autant !

    Donc, pour revenir à notre sujet, je vais finir la mise en page de mon site et dès que j’en ai terminé et que je vais me mettre au PHP, je repasserais ici pour montrer ce que j’ai fais.

    A plus tard !
    • On dit que le ridicule ne tue pas; On dit aussi que ce qui nous tue pas, nous rends plus fort; Alors pourquoi ne pas dire : Le ridicule nous rends plus fort !
    • On reproche aux gens de parler d'eux-même; C'est pourtant le sujet qu'ils traitent le mieux !

  14. #34
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par RinaBK Voir le message
    Coucou
    D’ailleurs, j’avais commencé à faire un fichier par classe, et en très peu de temps, je me suis retrouvée avec le double de fichiers sur le serveur. Donc, sans même avoir fini de faire toutes les pages du site, j’avais déjà 18 fichiers pour l’affichage de 5 pages, tout en sachant que j’avais encore à réaliser 5 pages supplémentaires. Donc, au final, je me serais retrouvée avec 28 fichiers au lieu de 15.

    Ceci-dit, tu as tout à fait raison sur le principe, et je ne peux rien dire là-dessus, mis à part qu’au final, on se retrouve avec beaucoup de fichiers.
    Bon, je t'explique une dernière fois et je n'y reviendrai plus. Ce que tu considères comme un inconvénient est un avantage car le but du jeu est précisément d'utiliser plusieurs fichiers pour créer une page afin d'avoir des scripts plus courts, plus lisibles et plus spécialisés.

    Sinon, à chaque évolution de ton code, la longueur de ta page va augmenter, devenir de plus en plus longue, interminable et pour comprendre les interactions dans ton script tu va être obligée de scroller sans cesse. Or c'est une grande perte de temps, de mémoriser le code qu'on vient de voir puis de scroller quelques centaines de lignes plus bas pour comprendre la logique du code. Dès que c'est un peu complexe tu vas y passer des plombes, avec un nombre d'allers retours fréquents, c'est improductif et complique le debugage car bien souvent le bug peut provenir d'un détail que l'on ne voit pas car justement on pense à regarder la logique d'ensemble. Alors que si tu as des fichiers distincts tu peux ouvrir deux fenêtres de ton éditeur de texte pour voir les deux (ou plus) codes côte à côte, pas besoin de scroll, tu visualises en direct, tu vois beaucoup mieux les interactions et le détail de chaque code.

    On voit que c'est le seul moyen d'avoir un code facilement évolutif. Après il faut faire preuve d'un minimum d'organisation bien entendu. Organiser tes répertoires et surtout respecter une convention de nommage comme je le disais plus haut. Si tu respectes la convention PSR4, tu mets grosso modo le chemin de ta classe pour appeler ta classe. Par exemple pour une classe de requête que tu mettrais dans le dossier "modele" du répertoire "admin" tu écriras dans ton code new admin\modele\nomdemaclasse();, donc ne me dit pas que tu vas être perdue puisque tu as l'adresse du fichier sous les yeux. Et donc plutôt que de scroller dans une page sans fin, en trois clic dans ton répertoire tu as le fichier qui s'affiche dans une fenêtre séparée.

    Ensuite quand on fait de la POO un peu évoluée, on crée (si possible) des classes généralistes (avec des fonctions de bases communes à différents scripts) que l'on va ensuite pouvoir étendre avec le mot clé "extends" pour les personnaliser en fonction des besoins ponctuels de tel ou tel script. On hérite ainsi des fonctions de la classe mère, tout en pouvant ajouter des méthodes ou en remplaçant (surchargeant) des méthodes de la classe mère. Et pour ne pas charger plus de classes que nécessaire on utilise donc là aussi une classe par fichier. Bref la logique, autant pour la souplesse d'utilisation, l'optimisation du code, que pour l'évolutivité et la facilité de programmation est de créer un fichier par classe.

    Tu ne t'en rends pas compte pour l'instant parce que tu n'utilises tes classes que pour grouper des fonctions, c'est un début et tu peux t'en contenter mais cela ne t'empêche pas d'essayer de prendre de bonnes habitudes pour pouvoir évoluer plus facilement. Ensuite tu n'auras plus à réfléchir si tu utilises toujours la même méthodologie. Le découpage en différents fichiers permet d'avoir un coût fixe à chaque fois que tu ajoutes une fonctionnalité car c'est toujours la même méthode, tu créer un fichier qui sera inclus dans ton code. Sinon si tu l'accumule dans une seule page, cette page va devenir de plus en plus longue, le coût de développement va augmenter très vite de façon exponentielle.

    Après je suis bien d'accord qu'il y a un point de bascule, jusqu'à un certain point tu gagneras du temps à ne faire qu'une page où tu mettras tout (comme le fichier que tu inclues et qui contient plusieurs classes), mais ce n'est pas la bonne méthode et tant qu'à apprendre autant le faire sur des choses simples, cela ne te prendras pas beaucoup plus de temps et tu prendras les bonnes habitudes, cela deviendra un réflexe et qui te permettras d'évoluer plus facilement, de même si tu crées de nouveaux sites tu sauras mieux comment t'y prendre.

    En fait si une classe ne sert que pour une page, on peut se demander l'intérêt de faire une classe, à part le fait d'exposer moins de variables dans le code et si les fonctions doivent partager des variables communes, pour le reste l'intérêt est nul par rapport à des fonctions. Quoi qu'il en soit si la classe devient longue elle va gêner la vision du reste du code dans laquelle elle est insérée, et à ce moment là on peut déjà trouver un intérêt de l'externaliser.

    C'est pour cela que je te disais d'externaliser tes classes de requêtes. C'est un premier pas vers une bonne organisation qui ne ne coûte pas cher (sauf à modifier tes habitudes) et tu ne risques pas de te tromper puisque l'architecture MVC est éprouvée depuis des lustres. Ce qui ne veut pas dire que toutes tes requêtes doivent nécessairement être externalisées, mais toutes celles qui sont dans une classe et que tu va pouvoir réutiliser dans d'autres pages.

    Si tu fais un fichier qui inclue de nombreuses classes tu ne fais que déplacer le problème car tu vas finir par avoir une longue page de classes dans laquelle il sera difficile de naviguer, et il faudra modifier cette page en fonction des besoins de chaque page si tu veux optimiser ton script. A quoi bon ce bin's puisqu'un système d'espace de nom et un autoloader bien fait permet de résoudre ces problèmes une fois pour toute.

    Ce que tu ne dois plus dire c'est qu'avoir de nombreux fichiers est un handicap. Le seul inconvénient est que pour modifier ton code cela te fais plusieurs fichiers à uploader, mais c'est tout et pour pas se prendre la tête on fait souvent l'upload de tout un répertoire ou sous répertoire pour ne pas avoir à sélectionner tel et tel fichier. Pour ce qui est de l'accès de php à ces différents fichiers, cela fait longtemps qu'il est optimisé pour ça, tous les sites sont faits de cette manière aujourd'hui, avec de nombreux fichiers pour créer une page. Et on ne fait pas ça pour le plaisir mais parce que c'est le seul moyen d'être certain de pouvoir évoluer en facilitant la maintenance.

    Enfin bref, je ne parlerai plus de ce sujet, mais à ta place je commencerais par prendre de bonne habitudes de suite, justement parce que ton code simple permet de t'entrainer facilement pour concevoir une architecture de répertoires/sous répertoires et organiser ton code de façon rationnelle. Ta méthode actuelle n'est pas mauvaise, mais tu ne pourras pas la généraliser si tu fais d'autres sites plus complexes donc autant prendre de bonnes habitudes en t'entrainant sur des choses simples. Dans un premier temps, fais le au moins pour tes classes de requêtes. Genre la classe C_PDO doit servir dans d'autres pages de ton site, elle n'a rien à faire dans un fichier inclus qui contient d'autre classes. mets en place l'autoloader pour t'exercer. Au final pour commencer à travailler en prenant de bonnes habitudes pour la POO cela revient juste à modifier la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if ($index == 'variables' || $index == 'fonctions' || $index == 'classes') { include('includes/'.$files); }
    //par
    if ($index == 'variables' || $index == 'fonctions') { include('includes/'.$files); }
    et charger tes classes par un autoload, tu peux bien faire ça sans changer le reste, c'est quand même pas la fin du monde.

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $requete = TABLE_DB['MESS'].' WHERE id='.$id;
    $affiche= $gestionTable->lire($requete,$ordre);
    Faut éviter ça. Là tu as une faille de sécurité majeure. Ok tu maitrise l'id, personne ne peux le modifier à ta place mais c'est une mauvaise habitude à ne pas prendre. Il faut toujours faire des requêtes préparées dès que tu as une variable dans ton code, d'une part parce que c'est mieux sécurisé et aussi parce que c'est mieux optimisé par php, c'est d'ailleurs ce qui est écrit dans la fonction quote qu'on utilise pour protéger ses variables si on ne fait pas de requête préparée (comme dit php c'est vivement déconseillé). Donc fais plutôt systématiquement des requêtes préparées et dans ta méthode "Lire" ajoutes un troisième paramètre dans lequel tu mettras le tableau que tu passeras en paramètre à la fonction execute().


    Vu que les nouveaux enregistrements, les modifications et les suppressions sont différentes à chaque page, j’ai supprimé les classes et j’ai laissé juste les fonctions : newsData(),updateData() et deleteData().
    Oui ça c'est justifiable. Tu pourrais éventuellement faire une classe mère et puis l'étendre mais bon, pas certain que tu y gagnes surtout si cette classe mère n'est pas utilisable dans un autre contexte. C'est pas la peine de faire des classes partout et pour tout dans ton contexte.

    Vu que je suis la seule à utiliser ces pages, j’ai viré les codes de contrôle sur les champs...Je me suis dit que se sera plus simple et quelques lignes de code en moins.
    Hum... c'est pas top, quelques lignes de code en moins c'est rien si tu t'organise bien, et il vaut mieux prendre de bonnes habitudes de développement dont on ne déroge pas, surtout en ce qui concerne les contrôles car ils ne sont pas utiles uniquement pour lutter contre le piratage, mais aussi pour faciliter le débuggage, et protéger ton code si tu venais à faire un essai malheureux qui pourrait avoir des conséquences inattendues. Personnellement, je code la partie administrateur de la même manière que la partie visiteur, cela m'évite de me poser des questions et au final ça va plus vite tout en étant plus sécure.

    Aller, bonne continuité pour la poursuite de tes mises à jour.

  15. #35
    Membre du Club Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Points : 64
    Points
    64
    Par défaut
    Salut !

    Non, je ne renie pas du tout ce principe, je le trouve juste et tout à fait avéré ! C’est juste que pour cette partie administration, je veux éviter d’avoir trop de fichiers et trop m’éparpiller pour l’instant. Cela étant dit, rien ne m’empêche plus tard de revenir sur cette partie administration et d’utiliser ce principe lorsque je serais déjà plus à l’aise avec tout ça. Je n’ai aucune inquiétude, je me connais suffisamment pour savoir qu’il y a de très forte chance que j’utilise ce principe plus tard. Mais pour l’instant, ce qui était important pour moi, c’est de travailler avec toutes ces nouvelles méthodes que tu m’as appris et les mettre en pratique en incluant mon ancienne méthode, histoire de ne pas trop me dé-familiarisé. Aussi, j’avais vraiment hâte de finir cette partie administration afin de pouvoir enfin commencer les pages du site (public).

    Je ne sais pas si cela vient de mes origines, vu qu’il parait que les Suisses sont lents, mais effectivement, j’ai besoin d’y aller gentiment et de ne pas trop tout changer mes habitudes trop vite. Je viens à peine d’apprendre une toute nouvelle façon de coder en PHP et je dois déjà me familiariser avec cela. De plus, j’ai aussi pas mal appris de nouvelles techniques sur le CSS et là aussi, je dois me familiariser avec tout ça. Pour la petite suissesse que je suis, ça fait vraiment beaucoup en peu de temps et ma cervelle n’est plus toute jeune non plus !

    Je pense, du moins c’est mon avis, que dans un premier temps, de coder sans trop m’éparpiller, histoire que dans ma petite tête, je ne sois pas trop perdue, en utilisant ces nouvelles méthodes c’est déjà un bon début. J’ai de toute façon gardé le lien direct à ce sujet dans mes favoris et je sais que je peux y revenir en tout temps si nécessaire et suivre toutes tes explications. Tu as été parfait dans tes explications et elles sont claires. De plus, j’ai testé en local pour bien comprendre le principe, donc pour l’instant, je ne m’inquiète pas trop et dès que je me sentirais prête pour passer à l’étape suivante et faire une classe par fichier, je reviendrais ici et j’aurais toutes les infos à ma disposition.

    Citation Envoyé par ABCIWEB Voir le message
    Faut éviter ça. Là tu as une faille de sécurité majeure. Ok tu maitrise l'id, personne ne peux le modifier à ta place mais c'est une mauvaise habitude à ne pas prendre. Il faut toujours faire des requêtes préparées dès que tu as une variable dans ton code, d'une part parce que c'est mieux sécurisé et aussi parce que c'est mieux optimisé par php, c'est d'ailleurs ce qui est écrit dans la fonction quote qu'on utilise pour protéger ses variables si on ne fait pas de requête préparée (comme dit php c'est vivement déconseillé). Donc fais plutôt systématiquement des requêtes préparées et dans ta méthode "Lire" ajoutes un troisième paramètre dans lequel tu mettras le tableau que tu passeras en paramètre à la fonction execute().
    Même si $id n’a pas été envoyé par $_POST ?

    Citation Envoyé par ABCIWEB Voir le message
    Hum... c'est pas top, quelques lignes de code en moins c'est rien si tu t'organise bien, et il vaut mieux prendre de bonnes habitudes de développement dont on ne déroge pas, surtout en ce qui concerne les contrôles car ils ne sont pas utiles uniquement pour lutter contre le piratage, mais aussi pour faciliter le débuggage, et protéger ton code si tu venais à faire un essai malheureux qui pourrait avoir des conséquences inattendues. Personnellement, je code la partie administrateur de la même manière que la partie visiteur, cela m'évite de me poser des questions et au final ça va plus vite tout en étant plus sécure.
    Oui, ce n’est pas faux ! C’est vrai que vu que je suis la seule à utiliser ma partie administration, j’ai tendance à moins me méfier de tout cela. Mais tu as raison, je ne devrais pas baisser ma garde parce qu’une erreur de manipulation c’est vite arrivé et on ne sait jamais ! Vaut mieux prévenir que guérir, comme on dit ^^



    Je viens de finir de mettre en place le design et coupé mes pages (header.php/footer.php) sur le site (public). J’ai aussi mis en place quelques fonctions globales qui, je pense, doivent rester en fonctions. Je les ai juste modifiées, car il n’est plus question d’utiliser mysqli.

    Code PHP : 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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
     
    <?php
    /************************************************************************
    **********		RÉCUPÉRATIONS DES INFORMATIONS CONCERANT LE SITE
    *********/
     
    function SelectSite() {
    	$connexion = C_PDO::getC();
    	$requete = 'SELECT * FROM adm_sites WHERE id=2';
    	$donnee = $connexion->query($requete);
    	$sortie = $donnee->fetch();
    	return define('SITE',array(
    				'id' => ($sortie->id),
    				'prefixe' => ($sortie->prefixe),
    				'nom' => ($sortie->nom)
    				));
    } SelectSite();
     
     
     
    /************************************************************************
    **********		RÉCUPÉRATIONS DES VARIABLES DE CONFIGURATIONS
    *********/
     
    function config($nom) {
    	$connexion = C_PDO::getC();
    	$requete = 'SELECT * FROM '.SITE['prefixe'].'_config WHERE nom="'.$nom.'"';
    	$donnee = $connexion->prepare($requete);
    	$donnee = $connexion->query($requete);
    	$sortie = $donnee->fetch();
    	return ($sortie->valeur);
    }
     
     
     
    /************************************************************************
    **********		RETOURNE LE NOMBRE D'ENREGISTREMENT D'UNE TABLE
    *********/
     
    function ndb($table) {
    	$connexion = C_PDO::getC();
    	$requete = 'SELECT * FROM '.SITE['prefixe'].'_'.$table;
    	$donnee = $connexion->prepare($requete);
    	$donnee = $connexion->query($requete);
    	$count = $donnee->rowCount();
    	return $count;
    }
     
     
    /************************************************************************
    **********		RETOURNE LA TAILLE D'UN FICHIER
    *********/
     
    function tailleFichier($fichier) {
    	//			Calcule de conversion entre Ko, Mo et Octet
    	$ko = pow(2,10);
    	$mo = pow(2,20);
    	$taille = filesize($fichier);
    	if ($taille < $ko) { $poids = $taille; }
    	elseif (($taille >= $ko) && ($taille < $mo)) { $poids = round($taille / $ko,1).'Ko'; }
    	else { $poids = round($taille / $mo,1).'Mo'; }
    	return $poids;
    }
    ?>

    Si plus tard, je peux les intégrer dans une classe, je le ferais, mais pour l’instant, vu que je ne sais pas trop où je vais, je préfère y aller pas à pas.

    Là, je suis en train de mettre en place ma toute première classe : Compteur de visite.
    J’avais déjà des fonctions : sreachCounter(), newCounter(),viewCounter(),updateCounter() et la fonction qui assemblait toutes ces fonctions que je plaçais en bas de chaque page sur site : Counter(). Je pourrais reprendre toutes ces fonctions, mais je me dis qu’autant revoir toute la gestion de ces fonctions et de faire une belle classe tout comme il faut. On verra bien si je m’en sors
    • On dit que le ridicule ne tue pas; On dit aussi que ce qui nous tue pas, nous rends plus fort; Alors pourquoi ne pas dire : Le ridicule nous rends plus fort !
    • On reproche aux gens de parler d'eux-même; C'est pourtant le sujet qu'ils traitent le mieux !

  16. #36
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par RinaBK Voir le message
    Salut !

    Je ne sais pas si cela vient de mes origines, vu qu’il parait que les Suisses sont lents, mais effectivement, j’ai besoin d’y aller gentiment et de ne pas trop tout changer mes habitudes trop vite. Je viens à peine d’apprendre une toute nouvelle façon de coder en PHP et je dois déjà me familiariser avec cela. De plus, j’ai aussi pas mal appris de nouvelles techniques sur le CSS et là aussi, je dois me familiariser avec tout ça. Pour la petite suissesse que je suis, ça fait vraiment beaucoup en peu de temps et ma cervelle n’est plus toute jeune non plus !
    Ok je préfère entendre ça, qu'entendre dire que le problème de l'autoload est que cela fait beaucoup de fichiers, car même si c'est vrai, ce n'est pas un problème mais un avantage. Il y a longtemps qu'on a abandonné l'idée de grouper beaucoup de code dans un même fichier car cela devient vite ingérable. Au lieu de cela on s'organise pour retrouver facilement les fichiers et la convention PSR4 permet justement de retrouver facilement ses classes puisque l'adresse du fichier est indiqué dans l'initialisation de la classe.

    Citation Envoyé par RinaBK Voir le message
    Même si $id n’a pas été envoyé par $_POST ?
    Au lieu de te poser des questions qui te font perdre du temps pour au final potentiellement faire des erreurs, tu ferais mieux de suivre les conseils de php sans te poser de questions. Si des variables existent dans la clause WHERE de la requête, on fait une requête préparée. Point barre.

    Citation Envoyé par RinaBK Voir le message
    Oui, ce n’est pas faux ! C’est vrai que vu que je suis la seule à utiliser ma partie administration, j’ai tendance à moins me méfier de tout cela. Mais tu as raison, je ne devrais pas baisser ma garde parce qu’une erreur de manipulation c’est vite arrivé et on ne sait jamais ! Vaut mieux prévenir que guérir, comme on dit ^^
    Même principe que ma réponse précédente. C'est surtout que tu perds du temps inutilement à savoir si tu dois plus ou moins te méfier, dans quelle mesure le code pourrait buguer ou être piraté, etc. Alors que si tu adoptes la bonne méthode dès le départ, tu traces sans te poser de questions, et tu gardes ton temps précieux pour t'occuper d'autre chose.


    Citation Envoyé par RinaBK Voir le message
    J’ai aussi mis en place quelques fonctions globales qui, je pense, doivent rester en fonctions.
    C'est à toi de voir si elles doivent rester dans des fonctions. Ce n'est pas choquant, tout dépend de ton organisation. Mais normalement quelque soit ton système d'organisation comme déjà dit à plusieurs reprises, on essaie toujours (sauf exception) de séparer les requêtes (qui font partie du modèle) du reste du code. C'est à dire que tu devrais avoir un fichier qui n'inclut que des fonctions de requêtes et un autre spécifique pour des fonctions utilitaires, comme la fonction qui retourne la taille d'un fichier.

    Après effectivement si tu n'as que cette fonction "tailleFichier" à mettre en plus dans ton fichier, on peut considérer qu'on peut faire une exception. Le problème est qu'ensuite on a tendance à multiplier les exceptions et ça devient le bin's. Donc ne surtout pas généraliser ce système car ensuite tu vas hésiter à faire des modifications parce que ça change tes habitudes, sauf que ce n'était pas une bonne habitude à prendre, mais précisément une exception à ne pas généraliser. Voilà pourquoi (et cela rejoint mes précédentes réponses) on évite de faire du bricolage au cas par cas en pensant qu'on va gagner du temps, mais on adopte une convention et ont la suit, l'exception devant être réellement une exception quand c'est vraiment très contraignant de faire autrement.

    Citation Envoyé par RinaBK Voir le message
    Je les ai juste modifiées, car il n’est plus question d’utiliser mysqli.
    Les fonctions "config" et "ndb" sont à corriger. Que vient faire un "query" dans une requête préparée? Ces requêtes ressemblent-elles au crud que tu as en exemple ? Pour reprendre le principe énoncé plus haut "SelectSite" et "config" doivent être une requête préparée (même si dans l'absolu on pourrait s'en passer pour SelectSite), et pour "ndb" une requête simple peut suffire puisqu'il n'y a pas de clause WHERE.

    Notes au passage (pour tes autres codes) qu'il y a aussi la méthode fetchAll() pour récupérer tous les résultats dans un tableau à la suite d'une requête préparée. Cela permet d'avoir l'équivalent d'une requête query dont le résultat peut être directement lu dans un tableau.

  17. #37
    Membre du Club Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Points : 64
    Points
    64
    Par défaut
    Je te remercie pour ta réponse
    Je regarderais et corrigerais tout ça en détail, dès que j'en aurais terminé avec l'architecture du site. Je me suis rendue compte qu'il y a un gros problème de visualisation lorsqu'on visionne le site depuis le téléphone. Là, ça fait tout le weekend que je cherche pourquoi tout est complètement déformé sur le téléphone. Le menu de navigation est tellement petit, qu'il est impossible de lire ou encore de cliquer sur un lien... Bref, la vraie catastrophe ! Donc, je suis bloquée à essayer de trouver une solution, mais pour l'instant ce n'est vraiment pas gagné. J'ai même refait complètement et différemment le design, mais quoi que je fasse, rien ne s'arrange. Bref, une vraie galère...
    • On dit que le ridicule ne tue pas; On dit aussi que ce qui nous tue pas, nous rends plus fort; Alors pourquoi ne pas dire : Le ridicule nous rends plus fort !
    • On reproche aux gens de parler d'eux-même; C'est pourtant le sujet qu'ils traitent le mieux !

  18. #38
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Bonjour,

    Oui mais les requêtes sont indépendantes du rendu html/css donc tu aurais mieux fait de résoudre ce problème avant de t'attaquer au problème de rendu. Je t'avais dit de passer plusieurs jours sur pdo... pour quelqu'un qui n'a pas l'habitude de cette interface ni de connaissances initiales en POO c'est le minimum pour bien maîtriser l'interface et exploiter correctement ses possibilités. Là tu utilises "query" dans une requête préparée, ce qui fait que ta requête n'est pas préparée et que tes variables ne sont pas protégées.

    Et si tu utilises "query" pour une requête avec une clause WHERE (ce qui est fortement déconseillé par php) il faut utiliser la fonction QUOTE pour protéger les variables. Pour un id tu peux t'en passer si tu es absolument certaine de fournir un entier, mais pour le "nom" dans ta fonction "config", pour peu qu'il contienne une apostrophe (') ou des caractères spéciaux ça va planter, sans compter que c'est une faille de sécurité majeure. Tout cela n'arriverait pas si tu utilisais des requêtes préparées pour toute requête contenant une clause WHERE avec des variables, non seulement c'est plus optimisé par php mais en plus il n'y a pas besoin d'utiliser la fonction QUOTE.

    A mon avis tu fais trop de choses à la fois et tu t'éparpilles. Certes si tu génères du html en php la mise en page en sera dépendante, mais les requêtes sont indépendantes du rendu et c'est d'ailleurs pour cette raison qu'on conseille de les séparer du reste du code, en se rapprochant du modèle MVC pour avoir des script plus courts, bien discerner les fonctionnalités et mieux prévoir les conséquences des modifications de code suivant dans la partie dans laquelle on intervient.

    Si tu donnes un coup de marteau à droite, puis un coup de pinceau à gauche, tu ne sauras jamais bien te servir ni du marteau, ni du pinceau. Pour dire qu'il faut s'immerger suffisamment dans la pratique d'un outil pour bien le maîtriser avant de passer à un autre. Ou alors on fait des exercices séparés dans des pages autonomes mais dans le cadre d'exercices, pas dans le cadre de la création d'un site finalisé. Sinon tu n'arrêteras pas de faire du zapping de l'un à l'autre par essais successifs pour obtenir un résultat, mais sans finalement savoir s'il n'y avait pas moyen de faire plus simple et tu risques de te compliquer la vie sans acquérir une base de connaissances solide, évolutive et réutilisable dans d'autres contextes.

    Pour les problèmes de sites adaptables bureau/portable, il faut regarder du côté du responsive design, et si tu as des questions cela te donneras l'occasion d'ouvrir un nouveau sujet dans le forum CSS. Mais comme déjà dit, étant donné que tu ne fais pas des exercices pour apprendre mais du code pour être directement intégré à un site, ce serait bien de terminer ce sujet pendant qu'il est encore d'actualité avant de passer à autre chose.

  19. #39
    Membre du Club Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Points : 64
    Points
    64
    Par défaut
    Justement, j'ai à peine commencé le codage PHP sur le site vu que j'ai fait à peine 3 petites fonctions et je vais pas m'amuser à continuer le codage si justement le site ne va pas. J'aime bien programmer, mais programmer dans le vide, sans trop savoir où je vais, ça ne sert pas à grand chose. OK, le design est une partie et le codage PHP en est une autre, mais les deux sont quand même lié . De plus, un sujet est justement ouvert pour mon problème, mais je n'ai toujours pas eu de réponse... Bref, j'ai qu'une seule cervelle et je ne peux pas tout faire en même temps. Un problème après l'autre, et en ce moment, temps que je ne sais pas ce qui se passe avec ce design, je ne touche pas au code PHP car je dois d'abord trouver ce qui ne va pas avec le CSS. Et mon site est justement fait en responsive et c'est justement ça qui coince. Lorsque j'utilisais du HTML avec simplement de la mise en forme CSS tout allait très bien. Mais on m'a conseillé de viré le HTML pour utiliser le CSS et maintenant tout va de travers. Ce weekend, j'ai recommencé plusieurs fois le design en responsive de différente manière. J'ai même copier/coller les codes CSS depuis le w3shool, mais rien à faire, je me retrouve toujours avec un menu tellement minuscule, que sur le téléphone, je ne peux même pas naviguer sur les pages du site. Bref, que je mette le menu avec de simple lien, ou que je réalise un menu type responsive, un menu déroulant, collant, de côté, sur le haut, etc. Les liens sont minuscules et le contenu des pages exorbitants. Dès que mon menu et mon contenu se trouve dans un grid-layer ou un CSS similaire, mon menu de navigation devient minuscule et inutilisable. Il y a que sur PC que le design est correct.. Et même si j'ai un sujet ouvert pour ce problème, je ne suis pas du genre à attendre sans rien faire qu'on me donne la solution. En attendant qu'on m'aide, je cherche aussi de mon côté une solution et tester différentes possibilités. Enfin bref, tout ça pour dire que ce weekend, je l'ai passé à décortiquer et refaire ce design, chercher, analyser chaque détail et chaque point, et je suis toujours à chercher pourquoi mon menu est minuscule quand on le visionne depuis un téléphone...
    • On dit que le ridicule ne tue pas; On dit aussi que ce qui nous tue pas, nous rends plus fort; Alors pourquoi ne pas dire : Le ridicule nous rends plus fort !
    • On reproche aux gens de parler d'eux-même; C'est pourtant le sujet qu'ils traitent le mieux !

  20. #40
    Membre du Club Avatar de RinaBK
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2021
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2021
    Messages : 92
    Points : 64
    Points
    64
    Par défaut
    Bon, j'en ai normalement bientôt terminé avec l'architecture du site
    Ceci-dit, je me posais une question... Je voulais mettre à jour les metas concernant la description et les mots clé du site. Je me demandais si je les enregistrais dans la base de donnée ou si je les mettais dans une variable, es-ce que cela risque de poser un soucis avec les moteurs de recherches ?

    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <meta name="description" content="Site personnel d’aide dans différents domaines qui vous propose des tutoriels en images et des outils à dispositions afin de vous aider dans certaines de vos démarches.">
    <meta name="keywords" content="Gwanda, Gremion, Wanda, Rebecca, RinaBK, Beka, Rina, BK, Tutoriel, HayDay, Sims, Decoration, decor, Outil">

    Changer par exemple en :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <?php
    define('SITE_DESCRIPTION','Site personnel d’aide dans différents domaines qui vous propose des tutoriels en images et des outils à dispositions afin de vous aider dans certaines de vos démarches.');
    define('SITE_MOTSCLE','Gwanda, Gremion, Wanda, Rebecca, RinaBK, Beka, Rina, BK, Tutoriel, HayDay, Sims, Decoration, decor, Outil');
    ?>
    <meta name="description" content="<?=SITE_DESCRIPTION;?>">
    <meta name="keywords" content="<?=SITE_MOTSCLE;?>">
    Ou est-ce que c'est fini ces balises meta, vu que certains navigateurs utilisent plutôt le contenu des pages pour leurs mots clé ??
    • On dit que le ridicule ne tue pas; On dit aussi que ce qui nous tue pas, nous rends plus fort; Alors pourquoi ne pas dire : Le ridicule nous rends plus fort !
    • On reproche aux gens de parler d'eux-même; C'est pourtant le sujet qu'ils traitent le mieux !

Discussions similaires

  1. Cherche Hébergement gratuit site web [PHP-MySQL]
    Par HULK dans le forum Gratuit
    Réponses: 15
    Dernier message: 20/01/2010, 23h53
  2. [MySQL] Aide à la création site en php mysql
    Par nbjr1858 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 03/06/2007, 17h10
  3. Extranet et les sites Internet : php/mysql
    Par kagura dans le forum Outils
    Réponses: 12
    Dernier message: 21/06/2006, 11h48
  4. créer son site en php/mysql entierement
    Par zimotep dans le forum Requêtes
    Réponses: 15
    Dernier message: 25/03/2006, 00h39
  5. Cherche Hébergement gratuit site web [PHP-MySQL]
    Par HULK dans le forum Hébergement
    Réponses: 11
    Dernier message: 23/08/2005, 15h04

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