web-dev-qa-db-fra.com

Pourquoi dois-je appeler 'exit' après la redirection via l'en-tête ('Location ..') en PHP?

Vous savez que si vous souhaitez rediriger un utilisateur dans PHP vous pouvez utiliser la fonction d'en-tête:

header('Location: http://smowhere.com');

Il est également bien connu que c'est une bonne pratique de mettre également un exit; Après l'appel header, pour empêcher l'exécution d'un autre code php. Ma question est donc la suivante: le code après l'appel à l'emplacement d'en-tête pourrait-il être exécuté efficacement? Dans quels cas? Un utilisateur malveillant peut-il ignorer complètement l'appel header('Location..')? Comment?

54
Nicolò Martini

le code après l'appel de localisation d'en-tête pourrait-il être exécuté efficacement?

Oui toujours. header n'est qu'une ligne de données demandant le navigateur à rediriger. Le reste de la page sera toujours servi par PHP et peut être consulté par le client en empêchant simplement l'exécution de la commande header).

C'est assez facile à faire avec un client en ligne de commande comme wget, par exemple, en lui disant simplement de ne pas suivre les redirections.

Bottom line: Si vous ne l'empêchez pas, PHP enverra le corps entier même après un appel header. Ce corps est entièrement disponible pour le destinataire sans aucun piratage spécial compétences.

58
Pekka 웃

Si vous redirigez mais que vous ne le faites pas die()/exit()le code est toujours exécuté et affiché.

Prenons l'exemple suivant:

admin.php:

if (authenticationFails)
{
    // redirect and don't die
}

// show admin stuff

Si vous ne vous assurez pas de terminer l'exécution après l'en-tête de l'emplacement every, l'utilisateur y aura accès.

25
Alix Axel

header() indique à PHP qu'un en-tête HTTP doit être envoyé ... Lorsque les en-têtes HTTP sont envoyés.

Et ceux-ci ne sont pas envoyés immédiatement lorsque vous écrivez l'appel à header (), mais quand il est temps de les envoyer (généralement, lorsque PHP doit commencer à envoyer le corps de la réponse) - qui pourrait être plus tard que vous ne le pensez, lorsque output_buffering est activé).

Donc, si vous appelez simplement header(), il n'y a absolument aucune garantie que le code écrit après cette instruction ne soit pas exécuté - sauf si vous indiquez qu'il ne doit pas, en utilisant exit/die.

L'utilisateur peut ignorer l'en-tête Location s'il le souhaite; mais cela ne changera rien au fait que le code après l'appel de header() pourrait ou non être exécuté: cette question est côté serveur.

8
Pascal MARTIN

Sans l'appel de sortie, le moment/l'heure exacte à laquelle votre script se terminera dépendra de deux facteurs:

  1. La rapidité avec laquelle le navigateur client réagit à la redirection
  2. Combien de temps il faut pour exécuter le reste de votre script.

Supposons que le navigateur démarre IMMÉDIATEMENT l'action de redirection au moment où il voit apparaître l'en-tête Location. Cela signifie qu'il fermera la connexion d'où provient la redirection, afin qu'il puisse commencer à se connecter au nouvel emplacement. Cela signifie généralement que le serveur Web mettra fin au script de redirection. Quel que soit le temps nécessaire à l'en-tête pour passer de serveur-> client et le processus de fermeture de lien TCP pour passer de client-> serveur est la durée pendant laquelle votre script peut continuer à s'exécuter.

1
Marc B

Le code PHP après un en-tête () sera exécuté. Parfois, cela est nécessaire, comme le montre exemple sur php.net. Pour vous assurer que ce n'est pas le cas, vous arrêtez complètement le flux du programme.

1
Alister Bulman

re: le code après l'appel à l'emplacement d'en-tête pourrait-il être exécuté efficacement?

Oui si vous ne fermez pas le script.

re: Dans quels cas?

Dans tous les cas.

n utilisateur malveillant peut-il ignorer complètement l'appel d'en-tête ('Location ..')?

Non, il sera exigé que l'utilisateur n'ait pas son mot à dire.

1
Steven smethurst