CLASSE SIMPLE DE GESTION DE FICHIERS

neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 - 28 déc. 2009 à 13:24
jadu Messages postés 217 Date d'inscription mercredi 26 juillet 2006 Statut Membre Dernière intervention 16 août 2018 - 4 janv. 2010 à 13:04
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/51020-classe-simple-de-gestion-de-fichiers

jadu Messages postés 217 Date d'inscription mercredi 26 juillet 2006 Statut Membre Dernière intervention 16 août 2018
4 janv. 2010 à 13:04
BONNE ANNÉE À TOUS !!!!

Je me suis permis d'adresser un MP à NEIGEDHIVER !
J'espère qu'il ne m'en voudra pas !
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
29 déc. 2009 à 00:13
J'ai pas tout ça en stock... Mon non-framework est en cours de développement. Ce que j'ai pour l'instant, des classes pour gérer :
- des fichiers de configuration
- la session utilisateur et les variables
- les cookies
- chiffrement/déchiffrement de données
- accès BDD (une surcharge de PDO incroyablement basique)
- les vues (= templates) avec gestion du titre, des js, css et meta
- des modules à insérer où on veut sur une page
- parcours de répertoires/fichier récursif avec filtres

Ca fait presque tout...
Pour les templates, comme je te le disais, ce ne sont que des fichiers PHP qui mettent en forme les variables passées à l'objet View histoire de les placer au bon endroit.
Pour les utilisateurs, j'ai une classe user hyper élémentaire qui se contente de charger les données du membre quand il se connecte (ou qu'il récupère sa session). Actuellement, je suis dans un contexte un peu particulier pour les membres, puisque je n'ai que 3 niveaux à gérer (et je n'en aurai pas plus) : membre connecté, modérateur, admin. Pas d'anonyme, c'est un serveur privé. Donc pour la gestion des permissions, j'ai rien du tout à part des méthodes du genre canAdmin(), isModo()...
C'est vraiment rien de transcendant, à la limite, ça doit pouvoir se développer tout ça en 2 jours. J'ai mis beaucoup de temps pour en arriver là, parce que j'ai essayé plein de choses, avec des librairies tierces, avec des morceaux de frameworks, j'ai fait, défait, refait (chaque fois depuis zéro) plusieurs fois, en prenant toujours en compte dans les nouvelles "versions" les problèmes que je rencontrais avant. J'ai un gros avantage : je suis pas pressé par le temps ou un client pour l'instant...

Pour l'accès à la BDD, ma classe est hyper basique :
- c'est un singleton (parce que je SAIS que je n'aurai pas besoin d'une autre base/connexion, de toute façon ça prend 2 minutes à modifier)
- étend PDO
- le constructeur charge la configuration de la connexion et établit la connexion via PDO (parent)
- c'est tout

Pour les autres classes, comme par exemple une classe Article, j'envisage simplement de lui coller des méthodes permettant d'effectuer des taches élémentaires : insérer un nouveau, récupérer les N derniers, etc. Avec __get() pour se dispenser du préfixe des champs dans la table, par exemple récupérer article_id avec $article -> id; sachant que la requête SQL va faire un violent SELECT * (ça en fera peut-être crier certains, mais le moteur du SGBD est prévu pour gérer ça) et les données stockées dans un tableau associatif dont la clé est le nom du champ. __get() va donc aller chercher la donnée en la préfixant comme il faut. C'est juste du confort lié à la contrainte que je m'impose de préfixer les noms de mes champs afin d'éviter les doublons dans le dictionnaire de données (parce que c'est mal).

Euh voilà, je sais pas quoi te dire d'autre... Les classes nécessaires pour la suite, j'ai rien de prévu pour le moment, je vais sûrement les écrire à la-rache.com quand j'en aurai besoin... Elles seront sûrement crades au début, puis quand je les aurai réécrites une bonne dizaine de fois (minimum) elles commenceront à ressembler à quelque chose.

Euh bon, mais si tu veux voir quelques fichiers, suffit de me filer ton mail en mp, tu verras un peu à quoi ressemble un non-framework en développement constant (c'est un peu de l'eXtreme Programming, mais en moins évolué mais encore plus souple, une méthode tellement agile que ça change tout le temps : un mélange la-rache.com et de MVC, de Merise (pas les fruits) et du bordel non commenté mais quand même bien rangé). Pis si tu veux voir, je suis curieux d'avoir un retour sur ce que ça t'inspire. Mais je doute qu'avec ça tu parviennes à faire un site aussi rapidement qu'avec ModX : moi je m'y retrouve dedans, c'est ma logique, ma façon de penser... Putain, c'est super intime en fait ! Arf !
alexarbitre Messages postés 5 Date d'inscription dimanche 1 mars 2009 Statut Membre Dernière intervention 28 décembre 2009
28 déc. 2009 à 22:07
Et sinon tu as des "briques" à me conseiller ? Des classes simples et légères pour gérer des templates, des utilisateurs, des artciles et une BDD ^^ je cherche et teste mais si tu as des idées je suis preneur :p

Je suis d'accord, le code porky a des de beaux jours encore.
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
28 déc. 2009 à 21:56
Je sais pas si on peut parler de framework, tellement c'est pas rigide (alors qu'un framework doit apporter un cadre stable, moi, ça bouge tout le temps et c'est modulable à outrance). C'est juste une approche différente, tirée de mon expérience (assez maigre, mais suffisante à mon goût) des frameworks existants. J'essaie de prendre ce qu'il y a de bien dans chaque : je ne fais pas d'un framework MCV un dogme, comme c'est le cas avec Zend ou même Kohana, où un contrôleur est une classe, une vue une classe, un modèle une classe très rigide avec un ORM... Chez moi, un contrôleur c'est juste du code. Une vue, c'est juste un fichier PHP (qui servait à ça à la base !) dans une classe (uniquement l'aspect pratique pour stocker les variables, locales et globales, des modules à afficher, rajouter des JS, CSS, Meta...). Pas de rigidité dans les modèles (peut-être pas assez, d'ailleurs).

Bref. Sinon, effectivement, quand on commence à coder en objet, on pense différemment. On ne voit pas une liste d'instructions, mais des briques qui s'emboitent. Pour moi, c'est une sorte de super Tetris lol

Sinon, le code spaghetti a encore de longues années devant lui :)
alexarbitre Messages postés 5 Date d'inscription dimanche 1 mars 2009 Statut Membre Dernière intervention 28 décembre 2009
28 déc. 2009 à 21:44
Oui donc en gros tu t'es écrit ton propre framework, comme ça tu sais avec quoi tu bosses, et tu codes pépère "ze finger in the noze" ...

Moi à la base je suis en réseaux, donc je code pour mon plaisir, sur le projet qu'on m'a proposé (parce que je suis le seul de la classe à ne pas cracher sur la prog) je me suis dit que ça serait intéressant de le faire en objet, un truc propre quoi ... Mais fatalement qui dit objet dit nouvelles manières de penser le programme, de le fractionner en modules et tout.

J'ai déjà développé un logiciel de gestion en PHP/MySQL (3.400 lignes pondues en 1 mois et demi) pour une entreprise nantaise, mais en procédural avec un code absolument immonde ^^
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
28 déc. 2009 à 21:02
Un framework complet... C'est pas une mince affaire... Bon, on va pas faire une disserte maintenant sur la question framework ou pas framework, pourquoi celui-là plutôt qu'un autre, ou quoi...

Pour ma part, j'avais commencé à utiliser CodeIgniter, Zend et Symfony ou autres me semblant trop lourds. Puis je suis passé à Kohana (fork en PHP5 de CI), puis j'ai laissé tomber... Je suis en train de revoir complètement mon approche de la structure de mes sites.
Je suis toujours dans une optique MVC, mais super allégée, ayant été très inspiré par le framework MVC no-framework de Rasmus Lerdorf (http://toys.lerdorf.com/archives/38-The-no-framework-PHP-MVC-framework.html). Mon approche est maintenant la suivante :
- des classes utilitaires en pagaille (relativement simples : une surcharge de PDO pour faciliter la connexion, une gestion de configuration, une classe View pour l'affichage, des trucs comme ça)
- pas d'ORM (après avoir vomi 3 fois sur chaque, j'ai fini par abandonner) : des classes "utilitaires" encore, comme ma classe User dont les méthodes ne sont que les actions possibles du membre (se connecter, afficher ses messages non lus, etc).
- mes contrôleurs sont des scripts à la racine de publication, accessibles directement (avec mod_rewrite quand même, parce que c'est plus joli plus propre)
- mes vues sont des fichiers PHP purs inclus dans la méthode render() de la classe View, où j'ai extrait mes variables de templates (donc accessibles directement par leur nom)
et des bricoles à côté pour me faciliter la vie (comme une classe Session qui ne sert qu'à configurer/démarrer la session, stocker les variables de session et des "variables flash", qui disparaissent après la prochaine page, accessibles une seule fois donc => inspiré de Kohana).

Ca simplifie quand même grandement les choses : j'ai quand même la séparation des différents métiers (MVC), tout en conservant une souplesse associée à une rapidité/simplicité de mise en oeuvre que Kohana ne pourra jamais m'offrir, malgré sa réputation dans ce domaine.

Cependant, je le reconnais : en ce qui me concerne en ce moment, je n'ai pas de contrainte de temps, pas de contrainte technique, je développe pour ma pomme... Je n'ai donc pas les mêmes considérations que toi ;)
alexarbitre Messages postés 5 Date d'inscription dimanche 1 mars 2009 Statut Membre Dernière intervention 28 décembre 2009
28 déc. 2009 à 20:39
De toutes façons j'ai tellement bidouillé ma classe cet aprèm que la page qu'elle est sensée afficher avec un template m'affiche une page blanche, sans erreur ni rien, donc je pense que je vais profiter de mes vacances pour glandouiller avant d'attaquer à la rentrée avec soit un framework complet (Zend ou autre) ou des classes déjà prêtes, vu que le site que je dois faire doit être livré en 4 mois (ce qui ne va pas être possible si je code mes classes).

Tout ça pour dire que cette classe risque fort de rester en l'état pour le moment ^^, mais je te remercie de tes conseils et j'aime bien ta façon de coder, donc je pense te "piquer" quelques fragments de code ;)

Bonne soirée !

Alex
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
28 déc. 2009 à 20:30
Les blocs try/catch ne sont pas indispensables dans une classe.
La classe est un outil, pas un contrôleur (ce n'est pas elle qui fait le traitement proprement dit). C'est le rôle du contrôleur de gérer les erreurs, pas d'une classe comme celle-là.
Ta classe peut lancer des exceptions en cas d'erreur, pas de problème. Utilise un bloc try/catch si dans ta classe tu utilises une autre classe susceptible de lever une exception.
Par exemple, une classe fonctionnant comme une Usine (motif de conception "Factory"), capable d'instancier des classes à la volée, voire même qui sont passées en paramètre, peut avoir besoin de l'API de réflexion pour s'assurer que la classe qu'elle s'apprête à instancier peut effectivement l'être (pas une classe abstraite, pas une interface, constructeur public si pas d'héritage, etc). Dans le cas où la classe n'existe pas, l'API de réflexion peut lever une exception. La classe Usine peut alors l'intercepter pour gérer ce problème et lancer une autre exception plus tard si besoin (ou pas).
alexarbitre Messages postés 5 Date d'inscription dimanche 1 mars 2009 Statut Membre Dernière intervention 28 décembre 2009
28 déc. 2009 à 16:48
Salut,

J'avoue que pour le coup du is_file(), j'ai l'air bien con ^^, je vais donc changer ça de suite.

Pour les noms des méthodes, je sais que je fais long, tout le monde me le dit, mais c'est ma manière de coder, j'aime bien "lire" un script au lieu d'essayer de le comprendre, mais je te rassure, mon prof de dev m'engueule souvent à cause de ça ^^.

Je vais tenir compte de tes remarques, voir ce que je peux optimiser, mettre des try/catch où il en faut, et poster la nouvelle version dans la soirée =)

Merci en tous cas !

Alex
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
28 déc. 2009 à 13:24
Salut,

Bon, ça existe déjà...

Désolé, j'ai pas pu résister à une blague super pourrie.

Bon, plus sérieusement.
is_file() renvoi un booléen : tester son résultat pour assigner true ou false en fonction de celui-ci, c'est un peu de l'ordre du pléonasme qui dit deux fois la même chose (et de la même manière, ce qui n'est vraiment pas très intéressant).
De plus, is_file() vérifie que le fichier est un fichier régulier. cela exclue les liens symboliques. C'est dommage, parce qu'un lien symbolique est tout aussi lisible qu'un fichier régulier. Mieux vaut utiliser is_file() quand on veut exclure les répertoires ET les liens symboliques. Sinon, il faut utiliser (file_exists($nom) && !is_dir($nom))

Ta classe est manifestement du PHP5 : pourquoi t'encombrer avec fopen(), fwrite() et fclose() alors que file_put_contents() fait tout ça tout seul comme il faut ? Cette série de trois fonctions est à préconniser quand on écrit un important volume de données et qu'on ne peut pas tout écrire en une seule ligne et que, donc, on a besoin de conserver le fichier ouvert (surtout quand on l'ouvre en RW). Dans le cas présent, file_put_contents() va ouvrir, écrire, fermer.

Etant donné les méthodes de ta classe, je ne comprends pas l'utilité de ce drapeau $existeFichier. Si le fichier n'existe pas, il n'y a qu'une méthode utilisable. Il me paraîtrait plus pertinent (mais là, c'est mon avis perso, en fonction de ma manière de coder) de spécifier le mode d'ouverture dans le constructeur et de créer le fichier si besoin. Si on est en lecture seule et que le fichier n'existe pas, on lance une exception (qui est quand même infiniment plus propre qu'un vulgaire die() ). Mais, je le répète, c'est très subjectif et je n'ai pas en tête la manière dont tu utilises ta classe.

Sinon, il pourrait être malin de modifier le drapeau $existeFichier, s'il vaut FALSE, une fois que le fichier a été créé... Ca permettrait d'écrire dans le fichier et ensuite de faire des opérations dessus (là, c'est juste pour rendre la classe plus généraliste sans préjuger de la manière dont on l'utilise).

C'est vrai que c'est beaucoup moins "complet" que d'autres sources/codes de templates. A tel point que euh... je n'en vois pas vraiment l'utilité : finalement, tu ne fais que mapper quelques fonctions dans une petite classe. Ca rend les choses un poil plus simples, mais tes fonctions ont des noms tellement longs qu'en fait pas tant que ça ^^
Faut bien avouer que
$object -> RetourneContenu();
c'est plus long que
$object -> read();

Parce qu'en fait, la méthode RemplacerOccurrence() ne fait pas plus qu'un simple str_replace()...
Cela dit, il est vrai qu'une classe est plus facile à surcharger que des fonctions natives... Mais, encore une fois, ça me paraît tellement light, que surcharger ta classe reviendrait quasiment à la réécrire ;)

Dernière chose : le nom de la méthode StockerContenuFichier() me paraît pas très clair au premier abord... Intuitivement, j'ai en tête que StockerContenuFichier signifie stocker le contenu dans le fichier... Manifestement, ce n'est pas ça puisque tu lis... D'un point de vue utilisateur (=développeur), le stockage correspond habituellement à une opération d'écriture d'une donnée du programme sur un support persistant (donc pas la RAM). Une opération de lecture par contre est intuitivement dans le sens inverse, pour rendre une donnée utilisable par le programme.

Voilà voilà, rien de méchant dans mon commentaire, hein. Faudrait mettre des smileys partout, donner des tapes amicales dans le dos, tout ça tout ça...