PHP End Tag ">"

PHP end tag ?

This is well documented. From the PHP Manual:

The closing tag of a PHP block at the end of a file is optional, and in some cases omitting it is helpful when using include() or require(), so unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.

Omitting the closing tag helps you prevent accidental whitespace or newlines from being added to the end of the file.

Why would one omit the close tag?

Sending headers earlier than the normal course may have far reaching consequences. Below are just a few of them that happened to come to my mind at the moment:

  1. While current PHP releases may have output buffering on, the actual production servers you will be deploying your code on are far more important than any development or testing machines. And they do not always tend to follow latest PHP trends immediately.

  2. You may have headaches over inexplicable functionality loss. Say, you are implementing some kind payment gateway, and redirect user to a specific URL after successful confirmation by the payment processor. If some kind of PHP error, even a warning, or an excess line ending happens, the payment may remain unprocessed and the user may still seem unbilled. This is also one of the reasons why needless redirection is evil and if redirection is to be used, it must be used with caution.

  3. You may get "Page loading canceled" type of errors in Internet Explorer, even in the most recent versions. This is because an AJAX response/json include contains something that it shouldn't contain, because of the excess line endings in some PHP files, just as I've encountered a few days ago.

  4. If you have some file downloads in your app, they can break too, because of this. And you may not notice it, even after years, since the specific breaking habit of a download depends on the server, the browser, the type and content of the file (and possibly some other factors I don't want to bore you with).

  5. Finally, many PHP frameworks including Symfony, Zend and Laravel (there is no mention of this in the coding guidelines but it follows the suit) and the PSR-2 standard (item 2.2) require omission of the closing tag. PHP manual itself (1,2), Wordpress, Drupal and many other PHP software I guess, advise to do so. If you simply make a habit of following the standard (and setup PHP-CS-Fixer for your code) you can forget the issue. Otherwise you will always need to keep the issue in your mind.

Bonus: a few gotchas (actually currently one) related to these 2 characters:

  1. Even some well-known libraries may contain excess line endings after ?>. An example is Smarty, even the most recent versions of both 2.* and 3.* branch have this. So, as always, watch for third party code. Bonus in bonus: A regex for deleting needless PHP endings: replace (\s*\?>\s*)$ with empty text in all files that contain PHP code.

Why doesn't PHP DOM include slash on self closing tags?

DOMDocument->saveHTML() takes your XML DOM infoset and writes it out as old-school HTML, not XML. You should not use saveHTML() together with an XHTML doctype, as its output won't be well-formed XML.

If you use saveXML() instead, you'll get proper XHTML. It's fine to serve this XML output to standards-compliant browsers if you give it a Content-Type: application/xhtml+xml header. But unfortunately IE6-8 won't be able to read that, as they can still only handle old-school HTML, under the text/html media type.

The usual compromise solution is to serve text/html and use ‘HTML-compatible XHTML’ as outlined in Appendix C of the XHTML 1.0 spec. But sadly there is no PHP DOMDocument->saveXHTML() method to generate the correct output for this.

There are some things you can do to persuade saveXML() to produce HTML-compatible output for some common cases. The main one is that you have to ensure that only elements defined by HTML4 as having an EMPTY content model (<img>, <br> etc) actually do have empty content, causing the self-closing syntax (<img/>) to be used. Other elements must not use the self-closing syntax, so if they're empty you should put a space in their text content to stop them being so:

<script src="x.js"/>           <-- no good, confuses HTML parser and breaks page
<script src="x.js"> </script> <-- fine

The other one to look out for is handling of the inline <script> and <style> elements, which are normal elements in XHTML but special CDATA-content elements in HTML. Some /*<![CDATA[*/.../*]]>*/ wrapping is required to make any < or & characters inside them behave mostly-consistently, though note you still have to avoid the ]]> and </ sequences.

If you want to really do it properly you would have to write your own HTML-compatible-XHTML serialiser. Long-term that would probably be a better option. But for small simple cases, hacking your input so that it doesn't contain anything that would come out the other end of an XML serialiser as incompatible with HTML is probably the quick solution.

That or just suck it up and live with old-school non-XML HTML, obviously.

HTML Tidy. Please don't add end tags

It can be solved this way:

<html>
<head>
<?php include "head.php" ?>
</head>
<body>
<?php include "header.php" ?>
<?php include "index.php" ?>
<?php include "footer.php" ?>
</body>
</html>

And the files index.php, head.php, header.php and footer.php now should have starting and closing tags. The program does that because it thinks you missed the closed tags. I saw Tidy HTML and it puts the close tags automatically.


Source: My experience doing sites this way

Opening and ending tag mismatch & Premature end of data in tag rss

This is due to the usage of <br> and other self closing tags. The dom tries to find the end like this <br/> where <br is start and /> is end. Modern browsers will not have problems with <tag> but the php dom function still wants you to keep the XML standard so you need to find al the <singletags> and replace them with <singletags /> then it works just fine.



Related Topics



Leave a reply



Submit