如何防止在线端渲染的空格?

The context

I have the following code:

<ul>
    <?php foreach($users as $user){ ?>
    <li>
        <?php echo $user->name ?>
    </li>
    <?php } ?>
</ul>

It renders:

<ul>
    </ul>

When there are $users, everything works well. However, when there aren't, the <ul> is rendered with blank spaces in it, making it not attributable with the CSS selector :empty.

I managed to solve the problem by doing this:

<ul><?php foreach($users as $user){ ?>
    <li>
        <?php echo $user->name ?>
    </li>
    <?php } ?></ul>

It renders:

<ul></ul>

Without the like breaks in the code, the list is now empty (even empty of blank spaces), but I'm afraid to leave it that way and some other programmer fix the indentation and break it.


My question

Is there a way to add line breaks to the code without adding blank spaces or breaks to the rendered html element?

My question is: Is there a way to add line breaks to the code without adding blank spaces or breaks to the rendered html element?

You could use HTML comments

<ul><!--
    <?php foreach($users as $user){ ?>
    --><li><!-- …

This is a technique also used to fight the space between inline block elements, if you want to keep the HTML code readable.

Or you could of course use output buffering, and then replace those spaces before you return the output to the client (rather complex, if you want to do it right.)

And probably the most simple solution of all to your actual problem:

Why output the ul element at all, if there are not going to be any list items?

Surround the whole block with an if that checks how many elements the array contains – and just don’t output any of that stuff if there aren’t any.

Do a test before :

  <?php if (isset($users) && count($users) > 0){ ?>
    <ul>
      <?php foreach($users as $user){ ?>
        <li>
          <?php echo $user->name ?>
        </li>
      <?php } ?>
    </ul>
  <?php } ?>

With that way, <ul> won't be created if there's no users, so no empty spaces.

Don't tab your php statements:

<ul>
<?php foreach($users as $user){ ?>
    <li>
        <?php echo $user->name ?>
    </li>
<?php } ?>
</ul>

PHP will remove everything starting at the <?php and ending at the ?> including the newline character. This is leaving the tab you have before your opening php tag.

You can break into a new line using:

echo "
" //this will break into a new line

But pay atention that you must use double quotes. Single quotes won't work:

echo '
' //this will output 

The full solution will be

<ul>
    <?php foreach($users as $user){ ?>
    <li>
        <?php echo $user->name ?>
    </li>
    <?php } echo "
" ?></ul>

I tested and it works. But if you are worried about future development and wan't to make things clear, I would use

if(isset($users)){?>
<ul>
    <?php foreach($users as $user){ ?>
    <li>
        <?php echo $user->name ?>
    </li>
    <?php } ?>
</ul>
<?php }else{ //comment explaining that this prevents CSS selector ?>
<ul></ul> 
<?php } ?>

I would go with this notation :

<ul><?php
    foreach($users as $user){
        ?><li><?php echo $user->name ?></li><?php
    }
?></ul>

It's still pretty readable, and HTML output contains no spaces that aren't needed, whether $users is empty or not!