0 follower

Réponses

Quand une application a terminé la prise en charge d'une requête, elle génère un objet response et l'envoie à l'utilisateur final. L'objet response contient des informations telles que le code d'état HTTP, les entêtes HTTP et le corps. Le but ultime du développement d'applications Web est essentiellement du construire de tels objets response pour des requêtes variées.

Dans la plupart des cas, vous devez travailler avec le composant d'application response qui, par défaut, est une instance de yii\web\Response. Néanmoins, Yii vous permet également de créer vos propres objets response et de les envoyer à l'utilisateur final comme nous l'expliquons dans ce qui suit.

Dans cette section, nous décrivons comment composer et envoyer des réponses à l'utilisateur final.

Code d'état

Une des premières choses que vous devez faire lorsque vous construisez une réponse est de déclarer si la requête a été correctement prise en charge ou pas. Cela se fait en définissant la propriété
code d'état qui peut prendre un des codes d'état HTTP valides. Par exemple, pour indiquer que la requête a été prise en charge avec succès, vous pouvez définir le code à 200, comme ceci :

Yii::$app->response->statusCode = 200;

Néanmoins, dans la plupart des cas, vous n'avez pas besoin de définir ce code explicitement. Cela tient au fait que la valeur par défaut de yii\web\Response::$statusCode est 200. Et, si vous voulez indiquer que la prise en charge de la requête a échoué vous pouvez lever une exception appropriée comme ceci :

throw new \yii\web\NotFoundHttpException;

Lorsque le gestionnaire d'erreurs intercepte l'exception, il extraie le code d'état de l'exception et l'assigne à la réponse. Concernant l'exception yii\web\NotFoundHttpException ci-dessus, elle est associée au code d'état HTTP 404. Les exception HTTP suivantes sont prédéfinies dans Yii :

Si l'exception que vous voulez lever ne fait pas partie de cette liste, vous pouvez en créer une en étendant la classe yii\web\HttpException, ou en en levant une à laquelle vous passez directement le code d'état. Par exemple :

throw new \yii\web\HttpException(402);

Entêtes HTTP

Vous pouvez envoyer les entêtes HTTP en manipulant la collection d'entêtes dans le composant response. Par exemple :

$headers = Yii::$app->response->headers;

// ajoute un entête  Pragma . L'entête Pragma existant n'est PAS écrasé.
$headers->add('Pragma', 'no-cache');

// définit un entête Pragma. Tout entête Pragma existant est supprimé.
$headers->set('Pragma', 'no-cache');

// retire un (des) entêtes Pragma et retourne les valeurs de l'entête Pragma retiré dans un tableau
$values = $headers->remove('Pragma');

Info : les noms d'entête ne sont pas sensibles à la casse. Les nouveaux entêtes enregistrés ne sont pas envoyés à l'utilisateur tant que la méthode yii\web\Response::send() n'est pas appelée.

Corps de la réponse

La plupart des réponses doivent avoir un corps qui transporte le contenu que vous voulez montrer à l'utilisateur final.

Si vous disposez déjà d'une chaîne de caractères formatée pour le corps, vous pouvez l'assigner à la propriété yii\web\Response::$content de la réponse. Par exemple :

Yii::$app->response->content = 'hello world!';

Si vos données doivent être formatées avant l'envoi à l'utilisateur final, vous devez définir les propriétés format et data. La propriété format spécifie dans quel format les données doivent être formatées. Par exemple :

$response = Yii::$app->response;
$response->format = \yii\web\Response::FORMAT_JSON;
$response->data = ['message' => 'hello world'];

De base, Yii prend en charge les formats suivants, chacun mis en œuvre par une classe formatter. Vous pouvez personnaliser les formateurs ou en ajouter de nouveaux en configurant la propriété yii\web\Response::$formatters.

Bien que le corps de la réponse puisse être défini explicitement comme montré ci-dessus, dans la plupart des cas, vous pouvez le définir implicitement en utilisant la valeur retournée par les méthodes d'action. Un cas d'usage courant ressemble à ceci :

public function actionIndex()
{
    return $this->render('index');
}

L'action index ci-dessus retourne le résultat du rendu de la vue index. La valeur de retour est interceptée par le composant response, formatée et envoyée à l'utilisateur final.

Parce que le format par défaut de la réponse est HTML, vous devez seulement retourner un chaîne de caractères dans une méthode d'action. Si vous utilisez un format de réponse différent, vous devez le définir avant de retourner les donnés. Par exemple :

public function actionInfo()
{
    \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    return [
        'message' => 'hello world',
        'code' => 100,
    ];
}

Comme mentionné plus haut, en plus d'utiliser le composant d'application response, vous pouvez également créer vos propres objets response et les envoyer à l'utilisateur final. Vous pouvez faire cela en retournant un tel objet dans une méthode d'action, comme le montre l'exemple suivant :

public function actionInfo()
{
    return \Yii::createObject([
        'class' => 'yii\web\Response',
        'format' => \yii\web\Response::FORMAT_JSON,
        'data' => [
            'message' => 'hello world',
            'code' => 100,
        ],
    ]);
}

Note : si vous êtes en train de créer vos propres objets response, vous ne pourrez par bénéficier des configurations que vous avez établies pour le composant response dans la configuration de l'application. Vous pouvez néanmoins, utiliser l'injection de dépendances pour appliquer une configuration commune à vos nouveaux objets response.

Redirection du navigateur

La redirection du navigateur s'appuie sur l'envoi d'un entête HTTP Location. Comme cette fonctionnalité est couramment utilisée, Yii fournit une prise en charge spéciale pour cela.

Vous pouvez rediriger le navigateur sur une URL en appelant la méthode yii\web\Response::redirect(). Cette méthode définit l'entête Location approprié avec l'URL donnée et retourne l'objet response lui-même. Dans une méthode d'action vous pouvez appeler sa version abrégée yii\web\Controller::redirect(). Par exemple :

public function actionOld()
{
    return $this->redirect('https://example.com/new', 301);
}

Dans le code précédent, la méthode d'action retourne le résultat de la méthode redirect(). Comme expliqué ci-dessus, l'objet response retourné par une méthode d'action est utilisé en tant que réponse à envoyer à l'utilisateur final.

Dans des endroits autres que les méthodes d'action, vous devez appeler la méthode yii\web\Response::redirect() directement, suivi d'un appel chaîné à la méthode yii\web\Response::send() pour garantir qu'aucun contenu supplémentaire ne sera ajouté à la réponse.

\Yii::$app->response->redirect('https://example.com/new', 301)->send();

Info : par défaut la méthode yii\web\Response::redirect() définit le code d'état à 302 pour indiquer au navigateur que la ressource requise est temporairement située sous un URI différent. Vous pouvez passer un code 301 pour dire au navigateur que la ressource a été déplacée de manière permanente.

Lorsque la requête courante est une requête AJAX, l'envoi d'un entête Location ne provoque pas automatiquement une redirection du navigateur. Pour pallier ce problème, la méthode yii\web\Response::redirect() définit un entête X-Redirect avec l'URL de redirection comme valeur. Du côté client, vous pouvez écrire un code JavaScript pour lire l'entête et rediriger le navigateur sur l'URL transmise.

Info : Yii est fourni avec un fichier JavaScript yii.js qui fournit un jeu d'utilitaires JavaScript, y compris l'utilitaire de redirection basé sur l'entête X-Redirect. Par conséquent, si vous utilisez ce fichier JavaScript (en enregistrant le paquet de ressources yii\web\YiiAsset ), vous n'avez rien à écrire pour prendre en charge la redirection AJAX. De l'information complémentaire sur yii.js est disponible à la section Scripts client.

Envoi de fichiers

Comme la redirection du navigateur, l'envoi de fichiers est une autre fonctionnalité qui s'appuie sur les entêtes HTTP spécifiques. Yii fournit un jeu de méthodes pour prendre en charge différents besoins d'envoi de fichiers. Elles assurent toutes la prise en charge de la plage d'entêtes HTTP.

Ces méthodes ont la même signature avec l'objet response comme valeur de retour. Si le fichier à envoyer est trop gros, vous devez envisager d'utiliser yii\web\Response::sendStreamAsFile() parce qu'elle fait un usage plus efficace de la mémoire. L'exemple qui suit montre comment envoyer un fichier dans une action de contrôleur.

public function actionDownload()
{
    return \Yii::$app->response->sendFile('path/to/file.txt');
}

Si vous appelez la méthode d'envoi de fichiers dans des endroits autres qu'une méthode d'action, vous devez aussi appeler la méthode yii\web\Response::send() immédiatement après pour garantir qu'aucun contenu supplémentaire ne sera ajouté à la réponse.

\Yii::$app->response->sendFile('path/to/file.txt')->send();

Quelques serveurs Web assurent une prise en charge spéciale de l'envoi de fichiers appelée X-Sendfile. L'idée est de rediriger la requête d'un fichier sur le serveur Web qui sert directement le fichier. En conséquence, l'application Web peut terminer plus rapidement tandis que le serveur Web est en train d'envoyer le fichier. Pour utiliser cette fonctionnalité, vous pouvez appeler la méthode yii\web\Response::xSendFile(). La liste suivante résume, comment activer la fonctionnalité X-Sendfile pour quelques serveurs Web populaires :

Envoi de la réponse

Le contenu d'une réponse n'est pas envoyé à l'utilisateur tant que la méthode yii\web\Response::send() n'est pas appelée. Par défaut, cette méthode est appelée automatiquement à la fin de yii\base\Application::run(). Vous pouvez néanmoins appeler cette méthode explicitement pour forcer l'envoi de la réponse immédiatement.

La méthode yii\web\Response::send() entreprend les étapes suivantes pour envoyer la réponse :

  1. Elle déclenche l'événement yii\web\Response::EVENT_BEFORE_SEND.
  2. Elle appelle yii\web\Response::prepare() pour formater les données de la réponse du contenu de la réponse.
  3. Elle déclenche l'événement yii\web\Response::EVENT_AFTER_PREPARE.
  4. Elle appelle la méthode yii\web\Response::sendHeaders() pour envoyer les entêtes HTTP enregistrés.
  5. Elle appelle la méthode yii\web\Response::sendContent() pour envoyer le corps de la réponse.
  6. Elle déclenche l'événement yii\web\Response::EVENT_AFTER_SEND.

Après que la méthode yii\web\Response::send() est appelée une fois, tout appel suivant de cette méthode est ignoré. Cela signifie qu'une fois la réponse expédiée, vous ne pouvez lui ajouter aucun contenu.

Comme vous pouvez le voir, la méthode yii\web\Response::send() déclenche plusieurs événements utiles. En répondant à ces événements, il est possible d'ajuster ou d'enjoliver la réponse.

Found a typo or you think this page needs improvement?
Edit it on github !