Débat : Règles d'écriture d'un site PHP (optimisation POO)
Le 2006-08-28 16:30:29, par KiLVaiDeN, Membre expert
Bonjour,
Je suis habitué à écrire des applications PHP depuis près de 6 ans, cependant, je voudrais faire un bond en avant, au niveau architecture de mes applications, car j'ai une experience faible au niveau programmation orientée objet sur cette plateforme.
Pour cela, j'ai voulu mettre en place un système de classes, permettant de simuler une sorte d'architecture multi-couches semblable à celles qui seraient disponible sous Java/J2EE par exemple.
Je me pose de sérieuse questions quant à la performance d'une telle application, utilisant les objets à tout va, je m'explique :
J'ai un ensemble de classes, chacune ayant un rôle défini ( des sortes de classes métier )
Chacune de ces classes, possède des méthodes permettant d'obtenir un résultat, également sous la forme d'un objet.
pour générer cet objet ( qui est un objet semblable à un DTO, Data Transfer Object ) je passe par d'autres classes d'une couche dite "basse" qui font la connexion à la base de données.
Pour que tout ce beau monde fonctionne ensemble, je ne vois pour l'instant que ce système, mais je le trouve trop lourd :
on arrive sur une page, par exemple index.php
on inclue un fichier ( /classes/index.phpClasses.php ) qui contient les inclusions de classes nécessaires pour le bon fonctionnement de cette page. Chaque page contient son propre "fichier d'inclusions", ceci est une optimisation que j'ai faite, au lieu de _tout_ charger pour chaque page.
je fais les traitements dont j'ai besoin sur l'index, avec les méthodes disponibles dans les classes qui ont étés loadées. Les classes loadées sont des classes métiers, qui elles-même, incluent d'autres classes de la couche "basse".
Je trouve que ça fait beaucoup d'inclusion à chaque fois que l'index.php est appellée...
Ma question est donc : quel sont les moyens standards, en developpement PHP, d'optimiser l'utilisation d'une telle architecture ?
Merci d'avance pour toute aide à ce sujet
Je suis habitué à écrire des applications PHP depuis près de 6 ans, cependant, je voudrais faire un bond en avant, au niveau architecture de mes applications, car j'ai une experience faible au niveau programmation orientée objet sur cette plateforme.
Pour cela, j'ai voulu mettre en place un système de classes, permettant de simuler une sorte d'architecture multi-couches semblable à celles qui seraient disponible sous Java/J2EE par exemple.
Je me pose de sérieuse questions quant à la performance d'une telle application, utilisant les objets à tout va, je m'explique :
Pour que tout ce beau monde fonctionne ensemble, je ne vois pour l'instant que ce système, mais je le trouve trop lourd :
Je trouve que ça fait beaucoup d'inclusion à chaque fois que l'index.php est appellée...
Ma question est donc : quel sont les moyens standards, en developpement PHP, d'optimiser l'utilisation d'une telle architecture ?
Merci d'avance pour toute aide à ce sujet
-
jeff_!Membre éclairésalut
ton projet est realisable, je me sers du mvc, toutes les requetes sont redigées par un regles de réecriture sur mon controller(index.php)
les fichiers(definission de classe) incluent sont géré par la fonction __autoload(php5) et par un fichier xml qui represente le file systeme
en moyene j'ai 80 fichier d'inclus, ca passe sur serveur dedier avec APC, mais sur un serveur mutualiser je pense que c'est pas la peine d'y penséle 28/08/2006 à 17:40 -
sekaijinExpert éminentBon après l'écriture d'un framework php maison pour diverse raison nous avons finalement ajouté à notre framework un charger de classes
le premier point est l'utilisation de require_once dans cette derninère et nom pas include include_once et ou require. je conseille donc de relire la doc au sujet de ses quatre fonctions php.
deuxième point le chargement de classes se fait toujours en chemin absolu à la mode unix. le charger transforme donc les c:\toto\truc en c:/toto/truc/
troisièmement les fichiers de définitions de classe portent le même nom que la classe avec sensibilité à la casse. MaClasse => MaClasse.class.php
Chaque classe en ayant besoin charge avec le chargeur de classe les classes qui lui sont nécessaire. sur le principe du import de java.
des packages regroupant fonctionnellement des classes sont définis ils portent le nom de leur classes principale. le chargeur de package utilise le chargeur de classes pour importer toutes les classes d'un package lorsque cela est nécessaire. cela permet de charger un groupe de classes sans avoir à se préoccuper des chargements dans chacune d'elles.
nous n'avons qu'un seul script exécutable dans le framwork
son algo est simple
Code : 1
2
3include loader; $ctrl = new controler(); $ctr->run();
enfin nous faisons un grand usage du pattern de façade.
une façade est une classe qui ne contient rien ou presque mais qui masque la complexité d'un ensemble fonctionnel. elle définit des méthodes qui masquent les classes sous jasante
par exemple dans le déroulement d'un processus nous faisons
Code : $db->getLastProduct();
le rôle de la façade est donc de présenter des méthodes de haut niveau d'abstraction. à elle de déterminer quel objet quelle classe invoquer.
dans ce contexte, la façade va être amené à instancier des classes. du coup elle va être amené à charger les fichiers de définition.
nous avons donc mis dans les façade le nécessaire
et nous concentrons les chargements des classes ainsi utilisé dans la façade. (nous utilisons le chargeur de classes pour cela)
au final nous n'avons que peux d'endroits ou se trouve des appels au chargement de classes ces principes en oeuvre donne un seul lieu dans le code ou est fait appel à require-once (il est donc possible de tracer les appels) les appels au chargeur sont concentré dans le contrôleur les classes principales des packages et les façades.
A+JYTle 28/08/2006 à 17:45 -
KiLVaiDeNMembre expertMerci pour ces informations
D'autres idées parmis vous ?
Si je comprend bien, on est toujours obligé de charger les classes métiers à chaque requête sur la page ? C'est lourd non ? Ca n'arrange pas les choses d'avoir des objets en static ( un peu du style singleton )
A+le 28/08/2006 à 20:33 -
jeff_!Membre éclairéon est toujours obligé de charger les classes métiers à chaque requête sur la page'arrange pas les choses d'avoir des objets en static ( un peu du style singleton )le 29/08/2006 à 10:13
-
guitou12Membre expérimentéPour ma part j'ai 1 et 1 seul require par page, il appelle ma librairie de connection à la base.
Dans cette librairie j'appelle toutes mes classes et tous mes fichiers d'options nécessaires au bon déroulement.
C'est une première solution qui ne fonctionne pas trop mal mais qui pourrait être optimisée à la sauce sekaijin (avec son loader). Ca mériterai que je me penche dessus mais bon là j'ai d'autres priorités de débugle 29/08/2006 à 10:20 -
berceker unitedExpert éminent__autoload à sauver ma vie. Depuis je dors mieux, je suis plus souriant, mon chat à un meilleur poil, doux et brillant.
Non sans dec depuis que je l'utilise les inclusions je m'en préocupe plus.
Dans mon appli j'ai plusieurs type de classe.
Requete, Data, Controleur et les metiers. Ils sont préfixé.
CtrlUtilisateur
ReqUtilisateur
...
Autoload ce charge de retrouver le fichier. Pour cela il faut respecté un peut le standart pour faciliter les choses. nom du fichier = nom de la classe.le 28/09/2006 à 17:18 -
sahidMembre actif
Envoyé par berceker united Code : 1
2
3
4
5
6
7function __autoload($class) { $mapClass = array( 'MaClass' => 'MaClass.class.php', 'Erf => 'Erf.event.class.php ); require_once( $mapClass[$class] ); }
sahidle 28/09/2006 à 17:25 -
berceker unitedExpert éminent
Envoyé par sahid mais bon ça revient presque à déclaré les include un par un.
Pour ma part j'utilise ceci. C'est fixeCode : 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15Function __autoload($ClasseName){ if(substr($ClasseName,0,7)=='Display'){ require_once($_SERVER['DOCUMENT_ROOT'].'/xxx/admin/scripts/php/classes/produits/affichages/'.strtolower(substr($ClasseName,7,strlen($ClasseName))).'.php5'); }elseif(substr($ClasseName,0,8)=='ReqMysql'){ require_once($_SERVER['DOCUMENT_ROOT'].'/xxx/admin/scripts/php/classes/produits/donnees/requetes/'.strtolower(substr($ClasseName,9,strlen($ClasseName))).'.php5'); }elseif(substr($ClasseName,0,12)=='ReqSQlServer'){ require_once($_SERVER['DOCUMENT_ROOT'].'/xxx/admin/scripts/php/classes/produits/donnees/requetes/'.strtolower(substr($ClasseName,12,strlen($ClasseName))).'.php5'); }elseif(substr($ClasseName,0,4)=='Data'){ require_once($_SERVER['DOCUMENT_ROOT'].'/xxx/admin/scripts/php/classes/produits/donnees/'.strtolower(substr($ClasseName,4,strlen($ClasseName))).'.php5'); }elseif(substr($ClasseName,0,4)=='Ctrl'){ require_once($_SERVER['DOCUMENT_ROOT'].'/xxx/admin/scripts/php/classes/produits/controleurs/'.strtolower(substr($ClasseName,4,strlen($ClasseName))).'.php5'); }else{ require_once($_SERVER['DOCUMENT_ROOT'].'/xxx/admin/scripts/php/classes/produits/middleware/'.strtolower($ClasseName).'.php5'); } }
le 28/09/2006 à 17:38 -
sahidMembre actiflol, vi sympa !
un peux complex quand meme
sinon je comprend pas pkoa tu dis que ca revien au meme que declarer les includes 1 par 1 ... je fais juste un require_once de mon fichier autoload.php ( qui contient cette fonction dans le fichier de démarrage de l'appli pi c ttle 28/09/2006 à 18:05 -
berceker unitedExpert éminent
Envoyé par sahid
Dans ta fonction tu places physiquement les correspondances donc si tu as 100 classes tu devras faire 100 index en gros. Autant que tu faces cela en une seul ligne. Nom de fichier = nom de la classe du moin presque mais tu le gères.le 28/09/2006 à 18:49