Lors du développement d'un site à l'aide de la structure Model-View-Controller, il existe un risque de mauvaise compréhension du rôle des contrôleurs, des vues et des modèles. Cela a pour conséquence de rendre les contrôleurs énormes et les modèles réduits, ce qui rend difficile le test et la prise en charge de votre application. L'objectif de cette section est de vous donner une idée générale du code qui peut être placé dans une classe de contrôleur, du code qui peut être placé dans une vue et du code qui peut être placé dans une classe modèle.
L'idée derrière le terme "contrôleur léger" est que typiquement, dans vos classes de contrôleur, vous mettez seulement le code qui :
$_GET
, $_POST
, $_FILES
et autres variables PHP);ViewModel
.Une classe contrôleur devrait éviter :
Pour un exemple de contrôleur "léger", regardez la classe CurrencyConverterController
ci-dessous.
Ce contrôleur fournit l'action "convert" dont l'objectif est de convertir une somme d'argent de l'euro vers
l'USD. L'utilisateur transmet le montant d'argent via la variable GET "amount".
class CurrencyConverterController extends AbstractActionController
{
// Currency converter model
private $currencyConverter;
// Constructor. It's purpose is to "inject" dependencies.
public function __construct($currencyConverter)
{
$this->currencyConverter = $currencyConverter;
}
// The "convert" action displays the converted money amount
public function convertAction()
{
// Get the money amount from GET
$amount = (float)$this->params()->fromQuery('amount', -1);
// Validate input data
if($amount<0) {
// Money amount is missing
$this->getResponse()->setStatusCode(404);
return;
}
// Pass the data to the CurrencyConverter model
$convertedAmount = $this->currencyConverter->convertEURtoUSD($amount);
return new ViewModel([
'amount'=>$amount,
'convertedAmount'=>$convertedAmount
]);
}
}
La méthode action du contrôleur ci-dessus est la suivante:
* Récupère les données transmises par l'utilisateur du site (ligne 16). Ces données font généralement
partie de l'objet Request
et peuvent être récupérées à l'aide de la méthode getRequest()
du contrôleur
ou du plugin de controleur Params
.
Effectue la vérification de base sur les données transmises par l'utilisateur (ligne 19), et si les données sont manquantes (ou non valides), définit un code d'erreur HTTP (ligne 21).
Transmet le montant en argent au modèle CurrencyConverter
(line 26) en appelant sa méthode
convertEURtoUSD()
. La méthode renvoie ensuite le montant converti.
Construit le conteneur de variable ViewModel
et lui transmet les données
résultantes (ligne 28). Ce conteneur de variables est également accessible dans la vue correspondante,
responsable de la présentation des données.
Parce que vous devez garder vos contrôleurs aussi légers que possible, la majeure partie de la logique métier de votre application doit être placée dans des classes modèles. Dans une application Model-View-Controller correctement conçue, les modèles semblent "énormes". Une classe de modèle peut contenir le code qui :
Effectue un filtrage et une validation de données complexes. Étant donné que les données que vous avez récupérées dans le contrôleur sont transmises à votre application depuis le monde extérieur, dans votre modèle, vous devez faire beaucoup d'efforts pour vérifier les données et vous assurer que les données ne causeront pas de dommage à votre système. Cela se traduit par un site web sécurisé résistant aux attaques des pirates informatiques.
Effectue la manipulation des données. Vos modèles doivent manipuler les données : par ex. charger les données depuis la base de données, enregistrer des données dans la base ou encore transformer les données. Les modèles sont le bon endroit pour stocker des requêtes de base de données, des fonctions de lecture et d'écriture de fichiers, etc.
Dans une classe modèle, il n'est pas recommandé de:
Accédez aux données des requêtes HTTP, $_GET
, $_POST
et autres variables PHP.
C'est le travail du contrôleur d'extraire ces données et les transmettre en entrée au modèle.
Produire du code HTML ou autre code spécifique à la présentation. Le code de présentation peut varier en fonction de la demande de l'utilisateur, il est préférable de le placer dans une vue.
Si vous suivez ces principes, vous constaterez que vos modèles seront faciles à tester car ils auront des entrées et des sorties clairement identifiées. Vous pourrez écrire un test unitaire qui transmet certaines données à la fin de l'entrée du modèle, récupère les données de sortie et vérifie que les données sont correctes.
Si vous n'êtes pas sûr d'où mettre certaines parties de code (dans un contrôleur ou dans un modèle), demandez-vous : est-ce une logique métier importante qui doit être testée avec soin ? Si la réponse est oui, vous devriez mettre le code dans un modèle.
Étant donné que la majeure partie de la logique est stockée dans des modèles, vos vues doivent être aussi simples que possible pour produire la présentation des données transmises dans le conteneur de variables. Dans une vue, vous pouvez :
Garder du code de balisage HTML statique.
Récupérez des données du conteneur de variables et les afficher.
Si un contrôleur transmet un certain modèle via un conteneur de variables, interrogez le modèle pour obtenir des données (par exemple, vous pouvez extraire des lignes de table d'une table de base de données et les afficher).
Contenir des opérations simples de contrôle de flux PHP, comme if
, foreach
, switch
, etc.
Cela permet de varier la présentation en fonction des variables transmises par le contrôleur.
La vue n'est pas recommandé pour :
Accéder aux données de la requête HTTP et aux variables globales PHP.
Créer des modèles, les manipuler et modifiez l'état de l'application.
Si vous suivez ces principes, vous constaterez que vos vues peuvent facilement être remplacées sans modifier la logique métier de votre application. Par exemple, vous pouvez facilement modifier la conception de vos pages web, ou même introduire des thèmes modifiables.