Les contrôleurs font partie du modèle d'architecture MVC (Modèle Vue Contrôleur). Ce sont des objets dont la classe étend yii\base\Controller. Ils sont chargés de traiter les requêtes et de générer les réponses. En particulier, après que l'objet application leur a passé le contrôle, ils analysent les données de la requête entrante, les transmettent aux modèles, injectent le résultat des modèles dans les vues et, pour finir, génèrent les réponses sortantes.
Les contrôleurs sont constitués d'actions qui sont les unités les plus élémentaires dont l'utilisateur final peut demander l'exécution. Un contrôleur comprend une ou plusieurs actions.
L'exemple qui suit présente un contrôleur post
avec deux actions : view
et create
:
namespace app\controllers;
use Yii;
use app\models\Post;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
class PostController extends Controller
{
public function actionView($id)
{
$model = Post::findOne($id);
if ($model === null) {
throw new NotFoundHttpException;
}
return $this->render('view', [
'model' => $model,
]);
}
public function actionCreate()
{
$model = new Post;
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
}
Dans l'action view
(définie par la méthode actionView()
), le code commence par charger le modèle en fonction de l'identifiant (ID) du modèle requis. Si le chargement du modèle réussit, l'action l'affiche en utilisant une vue nommée view
. Autrement, elle lève une exception.
Dans l'action create
(définie par le méthode actionCreate()
), le code est similaire. Elle commence par essayer de peupler une nouvelle instance du modèle avec les données de la requête et sauvegarde le modèle. Si les deux opérations réussissent, elle redirige le navigateur vers l'action view
en lui passant l'identifiant (ID) du nouveau modèle. Autrement, elle affiche la vue create
dans laquelle l'utilisateur peut saisir les entrées requises.
L'utilisateur final demande l'exécution des actions via ce qu'on appelle des routes. Une route est une chaîne de caractères constituée des parties suivantes :
Les routes se présentent dans le format suivant :
identifiant_de_contrôleur/identifiant_d_action
ou dans le format suivant si le contrôleur appartient à un module :
identifiant_de_module/identifiant_de_contrôleur/identifiant_d_action
Ainsi si un utilisateur requiert l'URL https://hostname/index.php?r=site/index
, l'action index
dans le contrôleur site
sera exécutée. Pour plus de détails sur la façon dont les routes sont résolues, reportez-vous à la section Routage et génération d'URL.
Dans les applications Web, les contrôleur doivent étendre la classe yii\web\Controller ou ses classes filles. De façon similaire, dans les applications de console, les contrôleurs doivent étendre la classe yii\console\Controller ou ses classes filles. Le code qui suit définit un contrôleur nommé site
:
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
}
Généralement, un contrôleur est conçu pour gérer les requêtes concernant un type particulier de ressource. Pour cette raison, l'identifiant d'un contrôleur est souvent un nom faisant référence au type de ressources que ce contrôleur gère.
Par exemple, vous pouvez utiliser article
comme identifiant d'un contrôleur qui gère des données d'articles.
Par défaut, l'identifiant d'un contrôleur ne peut contenir que les caractères suivants : lettres de l'alphabet anglais en bas de casse, chiffres, tiret bas, trait d'union et barre oblique de division. Par exemple, article
et post-comment
sont tous deux des identifiants de contrôleur valides, tandis que article?
, PostComment
et admin\post
ne le sont pas.
Un identifiant de contrôleur peut aussi contenir un préfixe de sous-dossier. Par exemple admin/article
représente un contrôleur article
dans le dossier admin
dans l'espace de noms du contrôleur.
Les caractères valides pour le préfixe des sous-dossiers incluent : les lettres de l'alphabet anglais dans les deux casses, les chiffres, le tiret bas et la barre oblique de division, parmi lesquels les barres obliques de division sont utilisées comme séparateurs pour les sous-dossiers à plusieurs niveaux (p. ex. panels/admin
).
Les noms de classe de contrôleur peut être dérivés de l'identifiant du contrôleur selon la procédure suivante :
Controller
.Ci-après sont présentés quelques exemples en supposant que l'espace de noms du contrôleur prend la valeur par défaut, soit app\controllers
:
article
donne app\controllers\ArticleController
;post-comment
donne app\controllers\PostCommentController
;admin/post-comment
donne app\controllers\admin\PostCommentController
;adminPanels/post-comment
donne app\controllers\adminPanels\PostCommentController
.Les classes de contrôleur doivent être auto-chargeables. Pour cette raison, dans les exemples qui précèdent, la classe de contrôleur article
doit être sauvegardée dans le fichier dont l'alias est @app/controllers/ArticleController.php
; tandis que la classe de contrôleur admin/post-comment
doit se trouver dans @app/controllers/admin/PostCommentController.php
.
Info : dans le dernier exemple,
admin/post-comment
montre comment placer un contrôleur dans un sous-dossier de l'espace de noms du contrôleur. Cela est utile lorsque vous voulez organiser vos contrôleurs en plusieurs catégories et que vous ne voulez pas utiliser de modules.
Vous pouvez configurer controller map (table de mise en correspondance des contrôleurs) pour outrepasser les contraintes concernant les identifiants de contrôleur et les noms de classe décrites plus haut. Cela est principalement utile lorsque vous utilisez des contrôleurs de tierces parties et que vous n'avez aucun contrôle sur le nommage de leur classe. Vous pouvez configurer controller map dans la configuration de l'application. Par exemple :
[
'controllerMap' => [
// declares "account" controller using a class name
'account' => 'app\controllers\UserController',
// declares "article" controller using a configuration array
'article' => [
'class' => 'app\controllers\PostController',
'enableCsrfValidation' => false,
],
],
]
Chaque application possède un contrôleur par défaut spécifié via la propriété yii\base\Application::$defaultRoute. Lorsqu'une requête ne précise aucune route, c'est la route spécifiée par cette propriété qui est utilisée. Pour les applications Web, sa valeur est 'site'
, tandis que pour les applications de console, c'est help
. Par conséquent, si une URL est de la forme https://hostname/index.php
, c'est le contrôleur site
qui prend la requête en charge.
Vous pouvez changer de contrôleur par défaut en utilisant la configuration d'application suivante :
[
'defaultRoute' => 'main',
]
Créer des actions est aussi simple que de définir ce qu'on appelle des méthodes d'action dans une classe de contrôleur. Une méthode d'action est une méthode publique dont le nom commence par le mot action
. La valeur retournée par une méthode d'action représente les données de la réponse à envoyer à l'utilisateur final. Le code qui suit définit deux actions, index
et hello-world
:
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public function actionIndex()
{
return $this->render('index');
}
public function actionHelloWorld()
{
return 'Hello World';
}
}
Une action est souvent conçue pour effectuer une manipulation particulière d'une ressource. Pour cette raison, les identifiants d'action sont habituellement des verbes comme view
(voir), update
(mettre à jour), etc.
Par défaut, les identifiants d'action ne doivent contenir rien d'autre que les caractères suivants : les lettres de l'alphabet anglais en bas de casse, les chiffres, le tiret bas et le trait d'union. Vous pouvez utiliser le trait d'union pour séparer les mots. Par exemple :
view
, update2
, et comment-post
sont des identifiants d'action valides, tandis que view?
et Update
ne le sont pas.
Vous pouvez créer des actions sous deux formes : les actions en ligne (inline) et les actions autonomes (standalone). Une action en ligne est définie en tant que méthode dans un contrôleur, alors qu'une action autonome est une classe qui étend la classe yii\base\Action ou une des ses classes filles. La définition d'une action en ligne requiert moins d'efforts et est souvent préférée lorsqu'il n'y a pas d'intention de réutiliser cette action. Par contre, les actions autonomes sont essentiellement créées pour être utilisées dans différents contrôleurs ou pour être redistribuées dans des extensions.
Les actions en ligne sont les actions qui sont définies en terme de méthodes d'action comme nous l'avons décrit plus haut.
Les noms des méthodes d'action sont dérivés des identifiants d'action selon la procédure suivante :
action
.Par exemple, index
donne actionIndex
, et hello-world
donne actionHelloWorld
.
Note : les noms des méthodes d'action sont sensibles à la casse. Si vous avez une méthode nommée
ActionIndex
, elle ne sera pas considérée comme étant une méthode d'action et, par conséquent, la requête de l'actionindex
aboutira à une exception. Notez également que les méthodes d'action doivent être publiques. Une méthode privée ou protégée ne définit PAS une action en ligne.
Les actions en ligne sont les actions les plus communément définies parce qu'elle ne requièrent que peu d'efforts pour leur création. Néanmoins, si vous envisagez de réutiliser la même action en différents endroits, ou si vous voulez redistribuer cette action, vous devriez envisager de la définir en tant qu'action autonome.
Les actions autonomes sont définies comme des classes d'action qui étendent la classe yii\base\Action ou une de ses classes filles. Par exemple, dans les versions de Yii, il y a yii\web\ViewAction et yii\web\ErrorAction, qui sont toutes les deux des actions autonomes.
Pour utiliser une action autonome, vous devez la déclarer dans la table de mise en correspondance des actions en redéfinissant les méthodes de la classe yii\base\Controller::actions() dans la classe de votre contrôleur de la manière suivante :
public function actions()
{
return [
// déclare une action "error" en utilisant un nom de classe
'error' => 'yii\web\ErrorAction',
// déclare une action "view" action en utilisant un tableau de configuration
'view' => [
'class' => 'yii\web\ViewAction',
'viewPrefix' => '',
],
];
}
Comme vous pouvez l'observer, les méthodes actions()
doivent retourner un tableau dont les clés sont les identifiants d'action et les valeurs le nom de la classe d'action correspondant ou des tableaux de configuration. Contrairement aux actions en ligne, les identifiants d'action autonomes peuvent comprendre n'importe quels caractères du moment qu'ils sont déclarés dans la méthode actions()
.
Pour créer une classe d'action autonome, vous devez étendre la classe yii\base\Action ou une de ses classes filles, et implémenter une méthode publique nommée run()
. Le rôle de la méthode run()
est similaire à celui d'une méthode d'action. Par exemple :
<?php
namespace app\components;
use yii\base\Action;
class HelloWorldAction extends Action
{
public function run()
{
return "Hello World";
}
}
Le valeur de retour d'une méthode d'action, ou celle de la méthode run()
d'une action autonome, représente le résultat de l'action correspondante.
La valeur de retour peut être un objet response qui sera transmis à l'utilisateur final en tant que réponse.
Dans les exemples ci-dessus, les valeurs de retour des actions sont toutes des chaînes de caractères qui seront traitées comme le corps de la réponse envoyée à l'utilisateur final. Les exemples qui suivent montrent comment une action peut rediriger le navigateur vers une nouvelle URL en retournant un objet response (parce que la méthode redirect() retourne un objet response) :
public function actionForward()
{
// redirect the user browser to https://example.com
return $this->redirect('https://example.com');
}
Les méthodes d'action pour les actions en ligne et la méthode run()
d'une action autonome acceptent des paramètres appelés paramètres d'action. Leurs valeurs sont tirées des requêtes. Pour les applications Web, la valeur de chacun des paramètres d'action est obtenue de la méthode $_GET
en utilisant le nom du paramètre en tant que clé. Pour les applications de console, les valeurs des paramètres correspondent aux argument de la commande.
Dans d'exemple qui suit, l'action view
(une action en ligne) déclare deux paramètres : $id
et $version
.
namespace app\controllers;
use yii\web\Controller;
class PostController extends Controller
{
public function actionView($id, $version = null)
{
// ...
}
}
En fonction de la requête, les paramètres de l'action seront établis comme suit :
https://hostname/index.php?r=post/view&id=123
: le paramètre $id
reçoit la valeur '123'
, tandis que le paramètre $version
reste null
(sa valeur par défaut) car la requête ne contient aucun paramètre version
.https://hostname/index.php?r=post/view&id=123&version=2
: les paramètres $id
et $version
reçoivent les valeurs '123'
et '2'
, respectivement.https://hostname/index.php?r=post/view
: une exception yii\web\BadRequestHttpException est levée car le paramètre obligatoire $id
n'est pas fourni par la requête.https://hostname/index.php?r=post/view&id[]=123
: une exception yii\web\BadRequestHttpException est levée car le paramètre $id
reçoit, de manière inattendue, un tableau (['123']
).Si vous voulez que votre paramètre d'action accepte un tableau, il faut, dans la définition de la méthode, faire allusion à son type, avec array
, comme ceci :
public function actionView(array $id, $version = null)
{
// ...
}
Désormais, si la requête est https://hostname/index.php?r=post/view&id[]=123
, le paramètre $id
accepte la valeur ['123']
. Si la requête est https://hostname/index.php?r=post/view&id=123
, le paramètre $id
accepte également la valeur transmise par la requête parce que les valeurs scalaires sont automatiquement convertie en tableau (array).
Les exemples qui précèdent montrent essentiellement comment les paramètres d'action fonctionnent dans les applications Web. Pour les applications de console, reportez-vous à la section Commandes de console pour plus de détails.
Chaque contrôleur dispose d'une action par défaut spécifiée par la propriété yii\base\Controller::$defaultAction. Lorsqu'une route ne contient que l'identifiant du contrôleur, cela implique que l'action par défaut de ce contrôleur est requise.
Par défaut, l'action par défaut est définie comme étant index
. Si vous désirez changer cette valeur par défaut, contentez-vous de redéfinir cette propriété dans la classe du contrôleur, comme indiqué ci-après :
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public $defaultAction = 'home';
public function actionHome()
{
return $this->render('home');
}
}
Lors du traitement d'une requête, une application crée un contrôleur en se basant sur la route requise. Le contrôleur entame alors le cycle de vie suivant pour satisfaire la requête :
beforeAction()
de l'application, celle du module (si module si le contrôleur appartient à un module) et celle du contrôleur. false
, les appels aux méthodes beforeAction()
qui devraient suivre ne sont pas effectués et l'exécution de l'action est annulée.beforeAction()
déclenche un événement beforeAction
auquel vous pouvez attacher un gestionnaire d'événement. afterAction()
du contrôleur, du module (si le contrôleur appartient à un module) et de l'application.afterAction()
déclenche un événement afterAction
auquel vous pouvez attacher un gestionnaire d'événement. Dans une application bien conçue, les contrôleurs sont souvent très légers avec des actions qui ne contiennent que peu de code. Si votre contrôleur est plutôt compliqué, cela traduit la nécessité de remanier le code pour en déplacer certaines parties dans d'autres classes.
Voici quelques meilleures pratiques spécifiques. Les contrôleurs :
Found a typo or you think this page needs improvement?
Edit it on github !
Signup or Login in order to comment.