Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Débat : Règles d'écriture d'un site PHP (optimisation POO)

Le , par KiLVaiDeN

0PARTAGES

1  0 
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

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de jeff_!
Membre éclairé https://www.developpez.com
Le 28/08/2006 à 17:40
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é
0  0 
Avatar de sekaijin
Expert éminent https://www.developpez.com
Le 28/08/2006 à 17:45
Bon 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 : Sélectionner tout
1
2
3
include loader;
$ctrl = new controler();
$ctr->run();
aucun include dans le code. seulement des chargement de classe appelée au travers du loader.

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 : Sélectionner tout
$db->getLastProduct();
$db est un objet qui représente la source de donnée ce n'est pas elle qui contient les donnée ni elle qui offre les méthode de manipulation de celle-ci. dans cet exemple ce sera plutôt un groupe de classes dédié à la manipulations de produit qui offre ce traitement.
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+JYT
0  0 
Avatar de KiLVaiDeN
Membre expert https://www.developpez.com
Le 28/08/2006 à 20:33
Merci 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+
0  0 
Avatar de jeff_!
Membre éclairé https://www.developpez.com
Le 29/08/2006 à 10:13
on est toujours obligé de charger les classes métiers à chaque requête sur la page
oui

'arrange pas les choses d'avoir des objets en static ( un peu du style singleton )
que ce soit un sigleton ou autre il faut que le fichier de definission soit inclu, apres tu peut optimisé ton code avec un cache de bas niveau comme APC
0  0 
Avatar de guitou12
Membre expérimenté https://www.developpez.com
Le 29/08/2006 à 10:20
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ébug
0  0 
Avatar de berceker united
Expert confirmé https://www.developpez.com
Le 28/09/2006 à 17:18
__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.
0  0 
Avatar de sahid
Membre actif https://www.developpez.com
Le 28/09/2006 à 17:25
Citation Envoyé par berceker united
_
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.
Code : Sélectionner tout
1
2
3
4
5
6
7
function __autoload($class) {
    $mapClass = array( 'MaClass' => 'MaClass.class.php',
                     'Erf        => 'Erf.event.class.php );

    require_once( $mapClass[$class] );
}
Plus besoin d'avoir le meme nom de fichier

sahid
0  0 
Avatar de berceker united
Expert confirmé https://www.developpez.com
Le 28/09/2006 à 17:38
Citation Envoyé par sahid
Code : Sélectionner tout
1
2
3
4
5
6
7
function __autoload($class) {
    $mapClass = array( 'MaClass' => 'MaClass.class.php',
                     'Erf        => 'Erf.event.class.php );

    require_once( $mapClass[$class] );
}
Plus besoin d'avoir le meme nom de fichier

sahid
Oui c'est l'une des astuces bravo mais bon ça revient presque à déclaré les include un par un.
Pour ma part j'utilise ceci. C'est fixe

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Function __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');
	}
}
0  0 
Avatar de sahid
Membre actif https://www.developpez.com
Le 28/09/2006 à 18:05
lol, 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 tt
0  0 
Avatar de berceker united
Expert confirmé https://www.developpez.com
Le 28/09/2006 à 18:49
Citation Envoyé par sahid
lol, 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 tt
Oui ça parait complexe parce que mes classe sont préfixé soit par Ctrl, Req,Data,... mais les noms de fichier porte le radicale. Mais là c'est figé quelque soit la classe que je rajoute tant que je respecte le protocole.

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.
0  0