Pourquoi omettrait-on l'étiquette de fermeture?

je lis c'est une mauvaise pratique d'utiliser la balise de fermeture PHP ?> à la fin du fichier. Le problème de l'en-tête ne semble pas pertinent dans le contexte suivant (et c'est le seul bon argument jusqu'à présent):

les versions modernes de PHP mettent le drapeau output_buffering en php.ini Si la mise en mémoire tampon de sortie est activée, vous pouvez configurer les en-têtes HTTP et les cookies après la sortie html parce que le code retourné n'est pas envoyé au navigateur immédiatement.

chaque Livre de bonnes pratiques et wiki commence par cette' règle ' mais personne n'offre de bonnes raisons. y a-t-il une autre bonne raison de sauter la balise php finale?

330
demandé sur Paracetamol 2010-12-10 19:00:39
la source

14 ответов

bien que je ne me souvienne d'aucune autre raison, envoyer des en-têtes plus tôt que le cours normal peut avoir des conséquences importantes. En voici quelques - uns qui me sont venus à l'esprit en ce moment:

  1. bien que les versions actuelles de PHP puissent avoir un tampon de sortie, les serveurs de production actuels 151980920 " sur lesquels vous déploierez votre code sont beaucoup plus importants que n'importe quelle machine de développement ou d'essai. Et ils ne sont pas toujours tendance à suivre immédiatement les dernières tendances de PHP.

  2. vous pourriez avoir des maux de tête pour inexplicable perte de fonctionnalité . Par exemple, vous mettez en œuvre une sorte de passerelle de paiement, et rediriger l'utilisateur vers une URL spécifique après confirmation réussie par le processeur de paiement. Si une erreur de PHP, même un avertissement, ou une fin de ligne excédentaire se produit, le paiement peut rester non traité et l'utilisateur peut toujours sembler non facturé. C'est aussi une des raisons pour lesquelles la redirection inutile est mauvaise et si la redirection doit être utilisée, elle doit être utilisée avec prudence.

  3. vous pouvez obtenir le type d'erreurs "chargement de Page annulé" dans Internet Explorer, même dans les versions les plus récentes. C'est parce qu'une réponse AJAX /JSON include contient quelque chose qu'elle ne devrait pas contenir, en raison des fins de ligne excessives dans certains fichiers PHP, tout comme je l'ai rencontré il y a quelques jours.

  4. si vous avez quelques téléchargements de fichiers dans votre application, ils peuvent casser aussi, à cause de cela. Et vous ne le remarquerez peut-être pas, même après des années, puisque l'habitude spécifique de rupture d'un téléchargement dépend du serveur, du navigateur, du type et du contenu du fichier (et peut-être d'autres facteurs que je ne veux pas vous ennuyer).

  5. enfin, de nombreux cadres PHP dont Symfony , Zend et Laravel (il n'y a aucune mention de cela dans les coding guidelines mais il suit la procédure) et le PSR-2 standard (point 2.2) exigent l'omission de l'étiquette de fermeture. Manuel PHP lui-même( 1 , 2 ), Wordpress , Drupal et beaucoup d'autres logiciels PHP je suppose, conseillent de le faire. Si vous avez simplement prenez l'habitude de suivre le standard (et configurer PHP-CS-Fixer pour votre code) vous pouvez oublier le problème. Sinon, vous aurez toujours besoin de garder la question dans votre esprit.

Bonus: quelques gotchas (actuellement un) liés à ces 2 caractères:

  1. même certaines bibliothèques bien connues peuvent contenir des terminaisons de ligne en excès après ?> . Un exemple est Smarty, même le plus récent version 2.* et 3.* direction de l'avoir. Ainsi, comme toujours, guetter pour le code de tiers . Bonus in bonus: un regex pour supprimer les fins inutiles de PHP: remplacer (\s*\?>\s*)$ par du texte vide dans tous les fichiers qui contiennent du code PHP.
290
répondu Halil Özgür 2014-07-10 16:17:55
la source

la raison pour laquelle vous devez laisser tomber la balise de fermeture php ( ?> ) est de sorte que le programmeur n'envoie pas accidentellement des caractères newline supplémentaires.

la raison pour laquelle vous ne devriez pas laisser tomber la balise de fermeture php est parce qu'elle provoque un déséquilibre dans les balises php et tout programmeur avec la moitié d'un esprit peut se rappeler de ne pas ajouter d'espace blanc supplémentaire.

ainsi pour votre question:

y a-t-il une autre bonne raison de ne pas fin de la balise php?

Non, il n'y a pas une autre bonne raison de sauter les balises php fin.

je terminerai avec quelques arguments pour ne pas déranger avec l'étiquette de fermeture:

  1. les gens sont toujours capables de faire des erreurs, peu importe à quel point ils sont intelligents. Adhérer à une pratique qui réduit le nombre d'erreurs possibles est (IMHO) une bonne idée.

  2. PHP n'est pas XML. PHP n'a pas besoin d'adhérer aux normes strictes de XMLs pour être bien écrit et fonctionnel. Si une étiquette de fermeture manquante vous ennuie, vous êtes autorisé à utiliser une étiquette de fermeture, ce n'est pas une règle fixe d'une manière ou d'une autre.

112
répondu zzzzBov 2010-12-15 22:09:41
la source

C'est un recommandation de style de codage de débutant , bien intentionné, et conseillé par le manuel .

décourageant toute utilisation de l'étiquette de fermeture ?> retarde simplement l'explication du comportement de base du traitement PHP et de la sémantique du langage pour éviter les problèmes peu fréquents. Il est pratique encore pour le développement de logiciels collaboratifs en raison de la compétence les variations dans les participants.

balise de fermeture variations

  • Le régulier ? > close tag est également connu sous le nom de T_CLOSE_TAG , ou donc "proche".

  • il comprend quelques autres incarnations, en raison de la magie de PHPs newline manger :

    ? > \n (saut de ligne Unix)

    ? > \r (retour Chariot, classique Mac)

    ? > \r \n (CR/LF, on DOS/Win)

    PHP ne supporte pas la ligne Unicode combo NEL (U+0085) cependant.

    les premières versions PHP ont eu IIRC compiler-ins limitant plate-forme-agnosticisme un peu (FI vient même d'utiliser > comme marqueur proche), qui est l'origine historique probable de l'évitement-étiquette proche.

  • souvent négligé, mais jusqu'à ce que PHP7 les supprime , le régulier <?php jeton d'ouverture peut être valide jumelé avec le rarement utilisé </script> comme jeton de fermeture Impair .

  • " dur balise de fermeture " n'est même pas celui -- viens terme pour l'analogie. Sur le plan de la conception et de l'utilisation, __halt_compiler devrait toutefois être considéré comme un jeton de proximité.

    __HALT_COMPILER();
    ?>
    

    qui a essentiellement le tokenizer jeter n'importe quel code ou des sections HTML simples par la suite. En particulier, les talons PHAR font usage de cela, ou de sa combinaison redondante avec ?> comme décrit.

  • de même, un nul return; remplace rarement dans les scripts include, le rendu de n'importe quel ?> avec un espace de fuite non efficace.

  • puis il y a toutes sortes de soft / faux close tag variations; moins connu et utilisé de façon sélective, mais généralement par commenté-out tokens:

    • Simple spacing // ? > pour échapper à la détection par tokenizer PHPs.

    • ou succédanés unicodes de fantaisie // ﹖﹥ (U+FE56 petit point D'interrogation, U+FE65 petit crochet D'ANGLE) qu'un regexp peut saisir.

    les deux ne signifient rien pour PHP , mais peuvent avoir des utilisations pratiques pour PHP-unknown ou semi-aware external toolkits. Encore une fois cat - les scripts joints viennent à l'esprit, avec le résultat // ? > <?php concaténations que inline-retain l'ancienne section de fichier.

il y a donc des solutions de rechange au fait d'omettre une étiquette de fermeture impérative, qui dépendent du contexte, mais qui sont pratiques.

baby-sitting Manuel de ?> close tags n'est pas très contemporain dans les deux cas. Il y a toujours eu des outils d'automatisation pour cela (même si seulement sed/awk ou regex-oneliners). En particulier:

phptags tag plus propre



https://fossil.include-once.org/phptags/

qui pourrait généralement être utilisé pour --unclose tags php pour le code de tiers, ou plutôt juste corriger n'importe quel (et tous) réels espaces/bom questions:

  • phptags --warn --whitespace *.php

Il gère également la --long tag de conversion etc. pour compatibilité entre l'exécution et la configuration.

51
répondu mario 2017-05-23 15:34:48
la source

Ce n'est pas une étiquette...

Mais si vous l'avez, vous risquez d'avoir un espace blanc après.

si vous l'utilisez ensuite comme une include en haut d'un document, vous pourriez finir par insérer de l'espace blanc (c.-à-d. du contenu) avant d'essayer d'envoyer des en-têtes HTTP ... ce qui n'est pas autorisé.

16
répondu Quentin 2010-12-10 19:02:45
la source

il est assez utile de ne pas laisser la fermeture ?> entrer.

le fichier reste valide pour PHP (pas une erreur de syntaxe) et comme @David Dorward l'a dit, il permet d'éviter d'avoir de l'espace blanc / ligne de rupture (tout ce qui peut envoyer un en-tête au navigateur) après le ?> .

par exemple,

<?
    header("Content-type: image/png");
    $img = imagecreatetruecolor ( 10, 10);
    imagepng ( $img);
?>
[space here]
[break line here]

ne sera pas valide.

mais

<?
    header("Content-type: image/png");
    $img = imagecreatetruecolor ( 10, 10 );
    imagepng ( $img );

volonté.

pour une fois, vous devez être paresseux pour être sécurisé .

12
répondu Shikiryu 2014-07-19 19:46:40
la source

selon the docs , il est préférable d'omettre l'étiquette de fermeture si elle est à la fin du dossier pour la raison suivante:

si un fichier est du code PHP pur, il est préférable d'omettre la balise de fermeture PHP à la fin du fichier. Cela empêche les blancs d'espace accidentels ou de nouvelles lignes étant ajoutées après la étiquette de fermeture de PHP, ce qui peut causer des effets indésirables parce que PHP commencera à la mise en tampon de sortie quand il n'y a aucune intention de la développeur d'envoyer une sortie à ce point dans le script.

Manuel PHP > Langue de Référence > syntaxe de Base > des balises PHP

10
répondu Asaph 2018-03-17 22:39:51
la source

il y a deux façons de voir les choses.

  1. code PHP n'est rien de plus qu'un ensemble de instructions de traitement XML , et donc tout fichier avec une extension .php n'est rien de plus qu'un fichier XML qui se trouve être analysé pour du code PHP.
  2. PHP se trouve justement à partager le format D'instruction de traitement XML pour ses balises open et close. Basé sur ça, des fichiers avec .php les extensions peuvent être des fichiers XML valides, mais elles n'ont pas besoin de l'être.

si vous croyez à la première route, alors tous les fichiers PHP doivent fermer les balises end. Pour les omettre créera un fichier XML invalide. Encore une fois, sans avoir une déclaration d'ouverture <?xml version="1.0" charset="latin-1" ?> , vous n'aurez pas de fichier XML valide de toute façon... Il n'est donc pas un problème majeur...

si vous croyez la deuxième route, qui ouvre la porte pour deux types de .php fichiers:

  • fichiers qui ne contiennent que du code (fichiers de bibliothèque par exemple)
  • fichiers qui contiennent du XML natif et aussi du code (fichiers de modèles par exemple)

basé sur cela, les fichiers codés sont OK pour finir sans une étiquette de fermeture ?> . Mais les fichiers XML-code ne sont pas OK pour finir sans une fermeture ?> car il invaliderait le XML.

mais je sais ce que vous pensez. Vous êtes en train de penser qu' est-ce important, vous n'allez jamais rendre un fichier PHP directement, donc qui se soucie si C'est XML valide. Eh bien, c'est important si vous concevez un modèle. S'il est valide XML/HTML, un navigateur normal n'affichera tout simplement pas le code PHP (il est traité comme un commentaire). Ainsi, vous pouvez vous débarrasser du modèle sans avoir à exécuter le code PHP à l'intérieur...

je ne dis pas que c'est important. C'est juste un point de vue que je ne vois pas exprimé trop souvent, alors quel meilleur endroit pour le partager...

personnellement, je ne ferme pas les tags dans les fichiers de bibliothèque, mais le font dans les fichiers de modèle... Je pense que c'est une préférence personnelle (et des lignes directrices de codage) basée plus que n'importe quoi de dur...

8
répondu ircmaxell 2014-07-19 19:49:40
la source

Eh bien, je connais la raison, mais je ne peux pas la montrer:

pour les fichiers qui ne contiennent que du code PHP, la balise de fermeture ( ?> ) n'est jamais permettre. Il N'est pas requis par PHP, et l'omettre empêche la injection accidentelle de blanc traînant l'espace dans la réponse.

Source: http://framework.zend.com/manual/en/coding-standard.php-file-formatting.html

6
répondu tawfekov 2014-07-19 19:45:04
la source

en plus de tout ce qui a déjà été dit, je vais ajouter une autre raison qui a été une énorme douleur pour nous de déboguer.

Apache 2.4.6 avec PHP 5.4 défauts de segmentation sur nos machines de production quand il y a de l'espace libre derrière la fermeture php étiquette. J'ai juste perdu des heures jusqu'à ce que j'ai finalement réduit le bug avec strace .

Voici L'erreur Qu'Apache lancers:

[core:notice] [pid 7842] AH00052: child pid 10218 exit signal Segmentation fault (11)
6
répondu Artem Russakovskii 2014-07-20 01:12:16
la source

Pros

Cons

Conclusion

je dirais que les arguments en faveur de l'omission de la balise regarder plus forte (aide à éviter les grands maux de tête avec header() + c'est PHP/Zend "recommandation"). J'admets que ce n'est pas la solution la plus "belle" que j'ai jamais vue en termes de cohérence syntaxique, mais qu'est-ce qui pourrait être mieux ?

4
répondu Frosty Z 2013-03-19 12:57:16
la source

"Est-il une autre bonne raison (autre que le problème d'en-tête) pour ignorer la balise de fermeture php?"

vous ne voulez pas produire par inadvertance caractères blancs étrangers lors de la production de sortie binaire, CSV données, ou d'autres non-sortie HTML.

4
répondu user1238364 2014-07-20 01:10:48
la source

comme ma question a été marquée comme une copie de celle-ci, je pense qu'il est correct d'afficher pourquoi pas omettre l'étiquette de fermeture ?> peut être pour certaines raisons souhaitées.

  • avec la syntaxe complète des Instructions de traitement ( <?php ... ?> ) PHP source est un document SGML valide, qui peut être analysé et traité sans problème avec SGML parser. Avec des restrictions supplémentaires, il peut aussi être valide XML/XHTML.

rien ne vous empêche d'écrire un code XML/HTML/SGML valide. documentation PHP en est conscient. Extrait:

Note: notez aussi que si vous intégrez PHP dans XML ou XHTML vous devrez utiliser le < ?le php ?> les étiquettes doivent rester conformes aux normes.

bien sûr la syntaxe PHP N'est pas stricte SGML / XML / HTML et vous créez un document, qui n'est pas SGML/XML/HTML, tout comme vous pouvez transformer HTML en XHTML pour être compatible XML ou non.

  • à un moment donné, vous pouvez vouloir concaténer des sources. Ce ne sera pas aussi facile que de simplement faire cat source1.php source2.php si vous avez une incohérence introduite en omettant la fermeture ?> tags.

  • sans ?> il est plus difficile de dire si le document a été laissé en mode PHP escape ou en mode PHP ignore (la balise PI <?php peut avoir été ouverte ou non). Vie est plus facile si vous laissez vos documents dans le mode PHP ignore. C'est comme travailler avec des documents HTML bien formatés par rapport à des documents avec des tags mal imbriqués, mal imbriqués, etc.

  • il semble que certains éditeurs comme Dreamweaver puissent avoir des problèmes avec PI left open [1] .

1
répondu doc 2014-07-08 22:01:28
la source

si je comprends bien la question, cela a à voir avec le tampon de sortie et l'effet que cela pourrait avoir sur la fermeture/fin des tags. Je ne suis pas sûr que cette question soit entièrement valable. Le problème est que le tampon de sortie ne signifie pas que tout le contenu est gardé en mémoire avant de l'envoyer au client. Cela signifie une partie du contenu est.

le programmeur peut rincer la mémoire tampon, ou la mémoire tampon de sortie ainsi fait l'option de mémoire tampon de sortie en PHP vraiment changer comment la balise de fermeture affecte de codage? Je dirais qu'il ne le fait pas.

et c'est peut-être la raison pour laquelle la plupart des réponses sont revenues au style et à la syntaxe personnels.

0
répondu Ruz 2010-12-17 20:07:39
la source

il y a 2 possibilités d'utilisation du code php:

  1. code PHP telles que la définition de la classe ou de la définition de la fonction
  2. utiliser PHP comme langage de modèle (i.e. dans les vues)

dans le cas 1. la balise de fermeture est totalement inutilisable, aussi je voudrais voir juste 1 (une) balise php ouverte et aucune balise de fermeture (zéro) dans un tel cas. C'est une bonne pratique car il s'code propre et distincte de la logique de présentation. Pour présentation de cas (2.) certains ont trouvé qu'il est naturel de fermer toutes les balises (même celles traitées par PHP), qui mènent à la confution, comme le PHP a en fait 2 cas d'utilisation séparée, qui ne devrait pas être mélangé: logique / calcul et présentation

0
répondu Daniele Cruciani 2015-12-31 14:47:52
la source

Autres questions sur php security http-headers