I keep reading it is poor practice to use the PHP close tag ?>
at the end of the file. The header problem seems irrelevant in the following context (and this
According to the docs, it's preferable to omit the closing tag if it's at the end of the file for the following reason:
If a file is pure PHP code, it is preferable to omit the PHP closing tag at the end of the file. This prevents accidental whitespace or new lines being added after the PHP closing tag, which may cause unwanted effects because PHP will start output buffering when there is no intention from the programmer to send any output at that point in the script.
PHP Manual > Language Reference > Basic syntax > PHP tags
"Is there another good reason (other than the header problem) to skip the ending php tag?"
You don't want to inadvertently output extraneous whitepace characters when generating binary output, CSV data, or other non-HTML output.
It's pretty useful not to let the closing ?>
in.
The file stays valid to PHP (not a syntax error) and as @David Dorward said it allows to avoid having white space / break-line (anything that can send a header to the browser) after the ?>
.
For example,
<?
header("Content-type: image/png");
$img = imagecreatetruecolor ( 10, 10);
imagepng ( $img);
?>
[space here]
[break line here]
won't be valid.
But
<?
header("Content-type: image/png");
$img = imagecreatetruecolor ( 10, 10 );
imagepng ( $img );
will.
For once, you must be lazy to be secure.
The reason you should leave off the php closing tag (?>
) is so that the programmer doesn't accidentally send extra newline chars.
The reason you shouldn't leave off the php closing tag is because it causes an imbalance in the php tags and any programmer with half a mind can remember to not add extra white-space.
So for your question:
Is there another good reason to skip the ending php tag?
No, there isn't another good reason to skip the ending php tags.
I will finish with some arguments for not bothering with the closing tag:
People are always able to make mistakes, no matter how smart they are. Adhering to a practice that reduces the number of possible mistakes is (IMHO) a good idea.
PHP is not XML. PHP doesn't need to adhere to XMLs strict standards to be well written and functional. If a missing closing tag annoys you, you're allowed to use a closing tag, it's not a set-in-stone rule one way or the other.
In addition to everything that's been said already, I'm going to throw in another reason that was a huge pain for us to debug.
Apache 2.4.6 with PHP 5.4 actually segmentation faults on our production machines when there's empty space behind the closing php
tag. I just wasted hours until I finally narrowed down the bug with strace.
Here is the error that Apache throws:
[core:notice] [pid 7842] AH00052: child pid 10218 exit signal Segmentation fault (11)
It's a newbie coding style recommendation, well-intentioned, and advised by the manual.
Eschewing ?>
however solves just a trickle of the common headers already sent causes (raw output, BOM, notices, etc.) and their follow-up problems.
PHP actually contains some magic to eat up single linebreaks after the ?>
closing token. Albeit that has historic issues, and leaves newcomers still susceptible to flaky editors and unawarely shuffling in other whitespace after ?>
.
Stylistically some developers prefer to view <?php
and ?>
as SGML tags / XML processing instructions, implying the balance consistency of a trailing close token. (Which btw, is useful for dependency-conjoining class includes to supplant inefficient file-by-file autoloading.)
Somewhat uncommonly the opening <?php
is characterized as PHPs shebang (and fully feasible per binfmt_misc), thereby validating the redundancy of a corresponding close tag.
There's an obvious advise discrepancy between classic PHP syntax guides mandating ?>\n
and the more recent ones (PSR-2) agreeing on omission.
(For the record: Zend Framework postulating one over the other does not imply its inherent superiority. It's a misconception that experts were drawn to / target audience of unwieldy APIs).
SCMs and modern IDEs provide builtin solutions mostly alleviating close tag caretaking.
Discouraging any use of the ?>
close tag merely delays explaining basic PHP processing behaviour and language semantics to eschew infrequent issues. It is practical still for collaborative software development due to proficiency variations in participants.
The regular ?> close tag is also known as T_CLOSE_TAG, or thus "close token".
It comprises a few more incarnations, because of PHPs magic newline eating:
?>\n (Unix linefeed)
?>\r (Carriage return, classic MACs)
?>\r\n (CR/LF, on DOS/Win)
PHP doesn't support the Unicode combo linebreak NEL (U+0085) however.
Early PHP versions had IIRC compile-ins limiting platform-agnosticism somewhat (FI even just used >
as close marker), which is the likely historic origin of the close-tag-avoidance.
Often overlooked, but until PHP7 removes them, the regular <?php
opening token can be validly paired with the rarely used </script>
as odd closing token.
The "hard close tag" isn't even one -- just made that term up for analogy. Conceptionally and usage-wise __halt_compiler should however be recognized as close token.
__HALT_COMPILER();
?>
Which basically has the tokenizer discard any code or plain HTML sections thereafter. In particular PHAR stubs make use of that, or its redundant combination with ?>
as depicted.
Likewise does a void return;
infrequently substitute in include scripts, rendering any ?>
with trailing whitespace noneffective.
Then there are all kinds of soft / faux close tag variations; lesser known and seldomly used, but usually per commented-out tokens:
Simple spacing // ? >
to evade detection by PHPs tokenizer.
Or fancy Unicode substitutes // ﹖﹥
(U+FE56 SMALL QUESTION MARK, U+FE65 SMALL ANGLE BRACKET) which a regexp can grasp.
Both mean nothing to PHP, but can have practical uses for PHP-unaware or semi-aware external toolkits. Again cat
-joined scripts come to mind, with resulting // ? > <?php
concatenations that inline-retain the former file sectioning.
So there are context-dependent but practical alternatives to an imperative close tag omission.
Manual babysitting of ?>
close tags is not very contemporary either way. There always have been automation tools for that (even if just sed/awk or regex-oneliners). In particular:
phptags tag tidier
https://fossil.include-once.org/phptags/
Which could generally be used to --unclose
php tags for third-party code, or rather just fix any (and all) actual whitespace/BOM issues:
phptags --warn --whitespace *.php
It also handles --long
tag conversion etc. for runtime/configuration compatibility.