PHP and newline characters

I admit, PHP is not my first language, so this may be well accepted in the PHP community. But as I see it, PHP treats newline characters in strange and unexpected ways. I’ve tested each of the following with PHP 4 (4.4.4 on my MacBook) and PHP 5 (5.2.1, also on my MacBook). But, from what I’ve read, this is not a bug, but a feature. At least, that’s what they say. I’ll let you decide.

Let’s look at some examples. (In the following examples, I’ve used “(space)” to indicate the presence of a space character since it wouldn’t be obvious otherwise.)

Example #1

PHP code:

<?php echo "Hello"; ?> world!

Result:

Hello world!

This works as you’d expect it to. The output is all on one line with one space in-between “Hello” and “world!”.

Example #2

PHP code:

<?php echo "Hello"; ?>
world!

Result:

Helloworld!

Here’s where things get weird. PHP eats whitespace when it thinks it isn’t important. So here we have a closing ‘php’ tag and some text that follows it on the next line. PHP discards the newline character altogether and you wind up with “Hello” and “world!” right next to each other.

Example #3

PHP code:

<?php echo "Hello"; ?>

world!

Result:

Hello
world!

In order to get the newline character back, you have to add an extra one.

Example #4

PHP code:

<?php echo "Hello"; ?>(space)
world!

Result:

Hello(space)
world!

Given that in example 2, PHP eats the newline character, you’d think this might come out as “Hello world!”, but you’d be wrong. In this case, the newline is preceded by a space, so PHP preserves BOTH.

Example #5

PHP code:

<?php echo "Hello"; ?>
(space)
world!

Result:

Hello(space)
world!

If you’ve been following closely this doesn’t surprise you, since you know from example 2 that PHP eats the newline character IF the line had ended with a closing PHP tag. So it doesn’t matter what you put on the following line (spaces or otherwise)— it will be placed at the end of the first line.

Example #6

PHP code:

Hello
<?php do_something(); ?>
<?php do_something_else(); ?>
world!

Result:

Hello
world!

Where you may think there would be at least two newline characters between “Hello” and “world!”, you only get one, since the others are at the end of a PHP block, so they die.

Conclusions

In the end, the behavior here is actually very consistent. If a PHP block is at the end of a line, the following newline character is suppressed. The official PHP FAQ speaks to this “feature”, and while there may be some merit to making PHP code look better, I’d prefer a more rigid approach to what happens to text outside of PHP tags.

At the very least, this behavior should be controllable via a PHP configuration setting. One that by default preserves the existing standard, but can be set through the ini_set function. Changing PHP to preserve all whitespace by default would likely have a harmful effect on existing code that relies on the current behavior.

But until this becomes an option, if you want to make sure you get a newline character following a closing PHP tag, add two instead of one.

TrackBack

TrackBack URL for this entry:
http://bradchoate.com/mt/feedback/tb/1399

7 Comments

This might be because some UNIX tools add a newline to files, and some PHP includes handling header-level output are written like that. If their inclusion would print the newline, the output would be started and headers prevented from being sent.

Brad Author Profile Page said:

@waffle.wootest.net: An interesting edge-case, but one that could be handled by only applying this rule to end-of-file situations. And even then, an ini setting to preserve whitespace should still trump that. For some, every byte is precious. Even the invisible ones.

Sure - although that would take the consistency out of it. It was only a theory, if one I deemed plausible.

An ini setting would be disastrous. Apply that to the file I described with trailing newline and headers being set, and consider some poor chap trying it on his home server (untweaked ini) and his host (diddled-with ini). Even if it didn't have those effects, I think it'd be a picky thing to have a setting for. PHP doesn't need more settings at this stage. ;)

Don said:

"...so this may be well accepted in the PHP community."

I assume you mean "may not be well accepted."

Brad Author Profile Page said:

@Don: No, I meant may be well accepted. I wasn't referring to my post, but to the behavior I am describing. I figure those that are more familiar with this peculiarity have come to terms with it, but I haven't.

JazzMan said:

I don't think this is a PHP problem. The behaviour you describe is happening outside the PHP block. As such, it is outside the control of PHP. It seems to be a symptom of how HTML is interpreted and thus is server and/or browser dependent.

Brad Author Profile Page said:

@JazzMan: Nope, this is definitely a PHP issue. It's even documented in their FAQ. You can observe this happening using the PHP command-line tool as well, so it's not something the browser is doing either.

About

This article was published on May 10, 2007 11:01 PM.

The article previously posted was Rotate 90º.

The next article is Number Fifteen.

Many more can be found on the home page or by looking through the archives.

Powered by Movable Type