L3 MVC.0
L3 MVC.0
L3 MVC.0
Dr Konate
ingngolo@gmail.com
Licence 3 UICI
Le Standard MVC
MVC (Model-View-Controller) est un modèle de conception de logiciel construit
autour de l'interconnexion de trois principaux types de composants (organises en
niveau d’abstraction) dans un langage de programmation tel que PHP, souvent
avec un fort accent sur les paradigmes de programmation orientée objet (POO).
Les trois types de composants sont appelés modèles, vues et contrôleurs.
Parlons d'eux individuellement, puis voyons comment ils s'assemblent :
- Le modèle est l'endroit où se trouve toute la logique métier d'une
application. La logique métier peut être tout ce qui est spécifique à la façon
dont une application stocke des données ou utilise des services tiers afin de
répondre à ses besoins. Si application doit accéder aux informations d'une
base de données, le code pour le faire sera conservé dans le modèle. Si elle
devait, par exemple, de récupérer des données sur les stocks ou de tweeter à
propos d'un nouveau produit, ce code sera également conservé dans le
modèle.
- La vue est l'endroit où tous les éléments de l'interface utilisateur de notre
application sont conservés. Cela peut inclure notre HTML, les feuilles de
style CSS et les fichiers JavaScript. Tout ce qu'un utilisateur voit ou avec
lequel il interagit peut-être conserve dans une vue. Parfois, ce que
l'utilisateur voit est en fait une combinaison de plusieurs vues différentes
dans la même requête.
- Le contrôleur est le composant qui relie les modèles et les vues entre eux.
Les contrôleurs isolent la logique d'un modèle des éléments de l'interface
utilisateur d'une vue, et gèrent la façon dont l'application répondra à
l'interaction de l'utilisateur dans la vue.
Les contrôleurs constituent le premier point d'entrée dans ce trio de composants,
car la requête est d'abord transmise à un contrôleur, qui instancie ensuite les
Dr Konate
ingngolo@gmail.com
Licence 3 UICI
1. Avantage du MVC
Dr Konate
ingngolo@gmail.com
Licence 3 UICI
3. Modèles de conception
Nous nous concentrerons sur le design pattern MVC, et pour y parvenir, nous
devrons utiliser d'autres design patterns plus simples pour les bibliothèques sur
lesquelles le framework est construit.
Les patrons de conception que nous allons passer en revue peuvent souvent être
appliqués au développement procédural, mais nous les examinerons dans le
contexte de la programmation orientée objet. Cela signifie que nous traiterons des
classes (plans contenant des propriétés et exécutant des fonctions) et de leur
interaction.
3.1 Singleton
Lorsque nous construisons des logiciels OOP, nous avons affaire à de nombreuses
classes. Bien qu'il soit idéal de concevoir ces classes de telle manière que plusieurs
instances puissent être actives simultanément, il y aura des moments où nous
n'aurons pratiquement besoin que d'une seule instance d'une classe, pour un but ou
un contexte spécifique.
Le singleton est un modèle de conception qui garantit qu'une classe ne peut avoir
qu'une seule instance à la fois. Une classe Singleton traditionnelle conserve une
instance d'elle-même dans une propriété statique interne et ne peut pas être
Dr Konate
ingngolo@gmail.com
Licence 3 UICI
instanciée (ou clonée) de la manière habituelle dont une classe non singleton peut
l'être.
Les singletons disposent d'une méthode d'accès à l'instance spéciale, qui renvoie la
propriété d'instance interne ou crée une nouvelle instance à retourner et à stocker.
3.2 Registres
Un registre est une classe qui peut stocker et renvoyer des instances de classes
standard. Pensez-y comme un manager d'équipe qui fait sortir des joueurs du
terrain de jeu et en envoie de nouveaux selon les besoins. Nous utilisons les classes
de registre pour gérer un nombre limité d'instances de classes, afin de ne pas avoir
à ré instancier sans cesse des classes dont le Registre contient déjà des instances.
Une autre façon de penser à une classe de registre est qu'elle nous aide à traiter les
classes normales comme des singletons, sans avoir à faire de ces classes normales
des singletons. Nous pouvons nous trouver dans une situation où nous avons
besoin de deux instances d'une classe. Nous avons peut-être besoin de nous
connecter à deux bases de données distinctes, mais nous ne voulons pas continuer à
nous y connecter.
Nous utilisons alors nous utilisons un Registre.
Dr Konate
ingngolo@gmail.com
Licence 3 UICI
3.3 Factory
Une Factory(fabrique) est une classe qui fournit une interface singulière pour créer
un nombre quelconque d'instances, sans avoir à spécifier le type de classe. Une
Factory choisira la classe à instancier en fonction des entrées sur la base d'une
entrée ou d'une logique interne.
Les fabriques sont utiles lorsque nous devons travailler sur une base de données,
mais que nous pouvons avoir affaire à un certain nombre de pilotes de bases de
données différents. Nous utilisons une classe Factory pour nous donner la classe de
pilote correcte, garantissant que tous nos pilotes sont conformes à une interface
standard.
3.4 Observer
Le modèle Observer décrit une structure dans laquelle il y a des émetteurs et des
récepteurs. Lorsque quelque chose change dans l'état d'un émetteur, il envoie un
message aux récepteurs qui lui sont associés, généralement en appelant l'une de
leurs fonctions.
Dr Konate
ingngolo@gmail.com
Licence 3 UICI
Dr Konate
ingngolo@gmail.com
Licence 3 UICI
1. Autoloading
Puisque nous allons écrire beaucoup de code, on peut supposer que nous voudrons
structurer le code clairement, pour éviter toute confusion au fur et à mesure que la
quantité de code augmente. Il existe plusieurs façons d'y parvenir, et l'une d'entre
elles consiste à garder des morceaux de code séparés dans des fichiers distincts.
Un problème qui découle de cette approche de la structure du code est que nous
devrons faire référence à la structure du code que nous devrons référencer en
morceaux de code externes à partir d'un point d'entrée unique.
Les requêtes adressées à un serveur web ont tendance à être acheminées vers un
seul fichier dans le répertoire webroot du serveur.
Par exemple : Les serveurs Web Apache sont généralement configurés pour
acheminer les requêtes par défaut vers index.php. Nous pouvons conserver tout le
code de notre framework dans ce seul fichier, ou nous pouvons le diviser en
plusieurs fichier et les référencer dans index.php. PHP fournit quatre instructions
de base pour nous permettre d'inclure des scripts externes dans le programme:
include, include_once, require, require_once
2. Namespaces
Une nouvelle addition particulièrement utile à PHP 5.3.0 est celle des espaces de
noms. Les espaces de noms permettent aux développeurs de définir leur code, en
Dr Konate
ingngolo@gmail.com
Licence 3 UICI
dehors de l'espace de noms global, afin d'éviter les conflits de noms de classes et
de mieux organiser leur code.
Nous utiliserons les espaces de noms dans presque toutes les classes que nous
écrirons, et ils ne sont pas particulièrement difficiles à utiliser.
3. Classe de base
Une des excellentes choses dans la construction d'un framework MVC, en utilisant
les paradigmes de la POO, est la possibilité de réutiliser son code, avec un effort
minimal. A tout moment, nous pouvons être amenés à ajouter des fonctionnalités
de base à la majorité de nos classes et une bonne base de POO nous aidera à le
faire.
Ce sont des méthodes qui ne servent qu’à une chose : changer la valeur d’un des
attributs de notre classe. Le setter prépare donc la donnée.
En fait, quand on met un attribut sur private, on n’y a plus accès depuis l’extérieur
de la classe. Par contre, il reste accessible à l’intérieur de la classe ! Un setter
permet alors de retourner l’objet lui-même avec return $this ; .
Dr Konate
ingngolo@gmail.com
Licence 3 UICI
La méthode magique sur laquelle nous allons nous concentrer est __call(). La
méthode __call() est une méthode d'instance, qui est invoquée chaque fois qu'une
méthode non-définie est appelée sur une instance de classe. En d'autres termes, si
vous appelez une méthode qui n'a pas été définie, la méthode __call() de la classe
sera appelée à la place.
class Car
{
public function __call($name, $arguments)
{
echo "hello world!";
}
}
$car = new Car();
$car->hello();
Nous ne définissons pas une méthode hello() sur la classe Car, mais lorsque nous
exécutons ce code, nous pouvons voir que la méthode __call() sera exécutée, et
produira la chaîne "hello world !". Ceci est dû au fait que la méthode __call() est
automatiquement invoquée lorsqu'une méthode non définie est appelée sur une
instance de Car.
Nous pouvons utiliser cela à notre avantage. Si nous attendons de nos
getters/setters qu'ils suivent le format de getProperty()/setProperty(), nous pouvons
créer une méthode __call() qui interprète exactement quelle propriété nous
cherchons à autoriser l'accès, et effectue les changements pertinents/renvoie les
données correctes. Comment ferions-nous cela, exactement ?
class Car
{
protected $_color;
protected $_model;
public function __call($name, $arguments)
{
$first = isset($arguments[0]) ? $arguments[0] : null;
switch ($name)
{
case "getColor":
return $this->_color;
case "setColor":
$this->_color = $first;
return $this;
Dr Konate
ingngolo@gmail.com
Licence 3 UICI
case "getModel":
return $this->_model;
case "setModel":
$this->_model = $first;
return $this;
}
}
}
$car = new Car();
$car->setColor("blue")->setModel("b-class");
echo $car->getModel()
Dr Konate
ingngolo@gmail.com
Licence 3 UICI
doit surcharger les getters/setters. De la même manière que nous avons implémenté
les getters/setters dans la classe Car, nous allons utiliser la méthode magique
__call() dans notre classe Base pour gérer les getters/setters
4. Configuration
4.1Tableau associatif
Les tableaux associatifs offrent le moyen de configuration le plus simple. Ils sont
faciles à comprendre pour tout développeur PHP, et encore plus simples à analyser.
Le Listing 4-1 montre un exemple de fichier de paramètres de base de données, et
le Listing 4-2 montre comment l'analyser.
Notre classe de configuration sera la première classe de fabrique que nous créons.
Nous voulons être capables de l'étendre dans le futur avec de nombreux types de
configuration, mais (en gardant nos objectifs à l'esprit) nous ne créerons qu'un seul
un seul pilote. Examinons d'abord la classe d'usine, comme indiqué dans le Listing
4-5.
namespace Framework
{
use Framework\Base as Base;
use Framework\Configuration as Configuration;
use Framework\Configuration\Exception as Exception;
class Configuration extends Base
{
/**
* @readwrite
*/
protected $_type;
/**
* @readwrite
*/
protected $_options;
protected function _getExceptionForImplementation($method)
{
return new Exception\Implementation("{$method} method not
implemented");
}
public function initialize()
Dr Konate
ingngolo@gmail.com
Licence 3 UICI
{
if (!$this->type)
{
throw new Exception\Argument("Invalid type");
}
switch ($this->type)
{
case "ini":
{
return new Configuration\Driver\Ini($this-
>options);
break;
}
default:
{
throw new Exception\Argument("Invalid type");
break;
}
}
}
}
}
La classe de Configuration est aussi la première que nous utiliserons avec les
getters/setters que nous avons créés avec la classe Base. Les deux $_type et
$_options peuvent être lus et écrits. Si vous vous référez à la méthode Base
__construct(), vous verrez qu'elle prend les clés/valeurs données dans le first
argument, et définit toutes les propriétés protégées qu'elle peut trouver. Si votre
tableau d'initialisation avait une clé d'options, la propriété protégée $_options
contiendrait cette valeur.
Nous vérifions d'abord que la valeur de la propriété $_type n'est pas vide. Si nous
ne savons pas comment déterminer la classe requise. Ensuite, nous utilisons une
instruction switch et la valeur de retour de $this->type, pour sélectionner et
instancier le type de classe correct.
Comme nous ne prendrons en charge que le type "ini" (pour l'instant), nous
lançons une ConfigurationExceptionArgument si le type requis n'est pas "ini". Si le
type requis est "ini", nous retournons une nouvelle instance, en passant à l'instance
les options fournies à la méthode de Configuration __construct(). Comme vous
pouvez le voir dans le Listing 4-6, la classe de Configuration est assez simple à
utiliser.
Listing 4-6. Creating a Configuration Object Using the Factory
$configuration = new Framework\Configuration(array(
Dr Konate
ingngolo@gmail.com
Licence 3 UICI
5. Le cache
Souvent, lorsqu'on traite de grandes quantités de données, on se heurte à des
goulots d'étranglement au niveau des performances. Ceux-ci peuvent se produire
pour plusieurs raisons, et peuvent être évités par une bonne mise en cache. Si vous
vous demandez ce que j'entends par "mise en cache", nous allons voir un exemple
dans un instant.
lieu d'aller chercher les mêmes données de la base de données à chaque fois que
nous en avons besoin, nous pourrions d'abord vérifier si les données sont stockées
dans le cache.
5.2 Le code
Dans un premier temps, on cree la classe du chache
namespace Framework
{
use Framework\Base as Base;
use Framework\Cache as Cache;
use Framework\Cache\Exception as Exception;
Dr Konate
ingngolo@gmail.com
Licence 3 UICI
{
throw new Exception\Argument("Invalid type");
}
Dr Konate
ingngolo@gmail.com
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: