What should be the last byte of a PHP file?

What should be the last byte of a PHP file?

by David Mudrák -
Number of replies: 11
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Plugins guardians Picture of Testers Picture of Translators
Hi there,

me and a friend of mine have encountered a problem with a character after "?>" at the end of a PHP file. It was a file in a language package that caused known problem "headers already sent". After some research, we found 0x0a byte (LF or line feed) as the very last byte of the file. When removing this character, everything started to work as expected.

My question is: what should be the last byte in a PHP file? I thought thoughtful it should be just 0x3e (">" character in the PHP closing tag) and that all other characters are unwanted trailing whitespace. But apparently, my VIM editor adds 0x0a (LF, line feed, end of line) at the end of every text file it touches. Is it correct behaviour? Can this extra byte after "?>" cause problems in some PHP environments?

I used Linux xxd utility and following command to get the last byte of every PHP file in Moodle:
find . -name "*.php" -printf '%p' -exec sh -c "xxd -s-1 {} | cut -d: -f2 | cut -c1-3" \;
A lot of Moodle PHP files end with 0x0a byte surprise and a lot of them end with 0x3e byte. Is there any rule in coding style about this? Thank you in advance for any info provided.

d.
Average of ratings: -
In reply to David Mudrák

Re: What should be the last byte of a PHP file?

by Mauno Korpelainen -

http://moodle.org/mod/forum/discuss.php?d=26003#p387936 Jean-Michel suggested totally removing

?>

at the end of php files (as odd as it sounds) based on

http://us.php.net/manual/en/language.basic-syntax.instruction-separation.php

Different text editors handle files in different ways and I haven't seen any documentation what editor is most suitable to handle php files without whitespace problems.

In reply to David Mudrák

Re: What should be the last byte of a PHP file?

by Mauno Korpelainen -

In principle everything after closing tag ?> (char 0x3e) is extra and could cause troubles. On the other hand php.net itself removes the closing delimiter from the end of some of its files - for example:

http://www.php.net/source.php?url=/source.php

In reply to Mauno Korpelainen

Re: What should be the last byte of a PHP file?

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers

In principle everything after closing tag ?> (char 0x3e) is extra and could cause troubles.

According to http://www.php.net/manual/en/language.basic-syntax.instruction-separation.php this is not so:

"The closing tag for the block will include the immediately trailing newline if one is present."

The problem here could be the definition of "newline", as different operating systems have different newline defintions. But according to the Moodle Coding Guidelines (http://docs.moodle.org/en/Development:Coding):

"3. All text files should use Unix-style text format (most text editors have this as an option)."

which I guess is the most cross-platform compatible newline setting.

So any .php file that ends with a 0x3f, 0x3e, 0x0a (and no additional whitespace-only trailing characters) is OK. Template files (.html files) are another different story.

Something like this will find the files that use the DOS/Windows or Mac newline convention, instead of the Unix one, for the closing tag: (run it from the Moodle root directory):

find . -type f -exec perl -e '$/ = undef; $_ = <>; print $ARGV . "\n" if ((m#\?>\r\n?$#s))' {} ";"

Maybe something like this could be used in the pre-commit hook of the CVS to catch this things before they enter the repository, coupled with the perl script shown at http://moodle.org/mod/forum/discuss.php?d=79683#p362067 to detect files with leading or trailing empty whitespace.

Saludos. Iñaki.

In reply to Iñaki Arenaza

Re: What should be the last byte of a PHP file?

by Martín Langhoff -

So a single newline is forgiven, 2 newlines or a space and a newline. In summary

  • ?>EOF is ok
  • ?>\nEOF is ok
  • ?>\n\nEOF is not ok
  • ?> \nEOF is not ok
In reply to Martín Langhoff

Re: What should be the last byte of a PHP file?

by Samuli Karevaara -
So the Windows "end of line" character after the ?> would not be ok? I.e.
  • ?>\r\nEOF
If so, then according to what Tim mentions ?>\n will break stuff on Windows boxes too, when checked out of CVS and converted to ?>\r\nEOF.

Computers are nice!
In reply to Samuli Karevaara

Re: What should be the last byte of a PHP file?

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
I don't know. PHP on windows may allow ?>\r\nEOF, someone should check.

I think I favour stripping all ?> from the ends of files in 2.0.
In reply to Tim Hunt

Re: What should be the last byte of a PHP file?

by David Mudrák -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Plugins guardians Picture of Testers Picture of Translators
I think so - for Windows platform, replace "\n" by "\r\n" in MartinL's summary. It makes sense as "newline" on Windows is defined as \r\n.

stripping all ?> from the ends of files

-1 for this. I have found closing tags useful when maintaining language files. As they are properly quoted by <?PHP and ?>, I am able to concatenate language files sent by a friend with mine ones and then re-save them in admin/lang.php. In this way, a lang pack maintainer can easily merge contributed files into standard lang pack. Of course there are other ways of doing this. But for some reason, omitting ?> smells for me mixed
In reply to Tim Hunt

Re: What should be the last byte of a PHP file?

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers

I have just tested this on Windows 2003, with PHP 5.2.5 (and apache 2.2.4).

It works with all the 'sensible' combinations: ?>\nEOF (Unix), ?>\r\nEOF (DOS/Windows) and ?>\rEOF (Mac).

I have tested it with a file called newline.php that only has:

<?php
 $value = 'somevalue';
?>

where I have tried the different newline combinations, and a second file called testnewline.php that has:

<?php
 require ('newline.php');
 setcookie ('mycookie', $value);
 phpinfo();
?>

And I get the cookie with the right value with all the combinations mentionned above.

Saludos. Iñaki.

In reply to Iñaki Arenaza

Re: What should be the last byte of a PHP file?

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
However, it is slightly more complicated than

"3. All text files should use Unix-style text format (most text editors have this as an option)."

Because CVS on windows will change \n to \r\n on checkout, and reverse that on checkin, so the file in your sandbox does use windows line endings, but that does not cause any problems (mostly).
In reply to David Mudrák

Re: What should be the last byte of a PHP file?

by Valery Fremaux -

Just for contributing to the discussion

there are two major issues having extra chars and new lines in php files, note that this is also the case for classes such as block class overloads.

  1. If the php file is a very early loaded file through include or requires, the libe might output spaces before an header() statement is found in the code, because of an applicative rerouting decision.
  2. Also if loaded too early in the page construction process, outputs extra chars before page really starts. Not damageable in standard, or transitional HTML, but letal for strict XHTML because of the XML header who MUST come at very start : <?xml ...

Obviously Martin confirmed to us what was "admited", so I suppose there is some standard php files filtering that will admit the last \n.

This do not apply for files that are knownly loaded very late, such as form parts, subviews, applicative controllers invoked from modules view switches etc.