30

I like the HEREDOC syntax, e.g. for edge cases of generated HTML that are not worth putting into a template.

The only thing that annoys me about it, though, is that the content, and the closing marker of a heredoc string adheres to the first column. This screws up nested code layouts:

class myclass 
 { 

    function __construct()
      { 
       $a = some_code();
       $b = some_more_code();
       $x = <<<EOT

line1
line2
line3
line4

EOT;    

        $c = even_more_code();
        $b = still_more_code();
        ...
        ...
        ...

you see what I mean.

Now this is probably not solvable using normal HEREDOC. Has anybody worked around this? My dream would be to have HEREDOC syntax with automatic indentation. But I guess this is not possible without writing some pre-compiler for the source files.

Am I correct?

5 Answers 5

31

Thank goodness this feature has finally landed in php 7.3 via RFC: Flexible Heredoc and Nowdoc Syntaxes

So now your example can cleanly be written as:

class myclass
{
    function __construct()
    {
        $a = some_code();
        $b = some_more_code();
        $x = <<<EOT

        line1
        line2
        line3
        line4

        EOT;

        $c = even_more_code();
        $b = still_more_code();
    }
}
1
11

That's a problem I often have too : the code is not well indented when I use heredoc, and I really like heredoc :-(

A "bigger" problem is when you select a whole block of code, press "tab" (or any equivalent in your IDE) to indent it more because you added a condition arround it or anything... And it breaks the heredoc strings : you have to go un-indent them by hand :-(

Unfortunatly, I've never seen any tool like the one you're describing...


A solution, I suppose, would be to put the heredoc string in another file, and include it -- the include like could be indented normally ; but it would also mean one more file to load, which would make the code less clear.

3
  • Yup, including another file brings too much confusion... I'm thinking about building a "pre-compiler" like LESS for CSS, but it seems too much of an effort (and an extra step) for too little gain. Too bad!
    – Pekka
    Commented Feb 21, 2010 at 13:27
  • 7
    Using some kind of "pre-compiler" would also mean that the code you write and see (in your IDE/editor) is not the code that gets executed -- and this will be source of confusions, one day or another... Commented Feb 21, 2010 at 13:28
  • Off-topic: I suggest using an editor that has decent parsing capabilities to auto-indent code. Good IDEs (such as PhpStorm) don't let you indent HEREDOC closing tags even when explicitly writing tabs. Commented Nov 9, 2016 at 10:58
4

I just discovered an odd workaround for anyone still wondering how to do this. Indent your first line that starts the HEREDOC. Your second line, which is the first line of the HEREDOC, has to have no whitespace, so leave it as a blank line. Start a new line after that, indent it and write your code. Then complete the HEREDOC, again with no white space. Visually you'll get all of your code indented except for the completion of the HEREDOC. Highlight + TAB still an issue, but at least the code is more readable within control loops, etc, now.

           $html = <<< HTML                    //indented line
                                               //leave this line empty
           <div>                               //indented line
                <div>$variable</div>           //indented line
           </div>                              //indented line
HTML;                                          //no white space, not indented
1
  • 2
    I rolled back this answer to revision 1. The edits made by @bgs completely destroyed the whole point that Wes was trying to make. Commented Sep 25, 2014 at 20:49
3

You cannot ident heredocs or nowdocs in PHP. This is my workaround:

function foo() {
    $a = 123;
    $b = 456;
    $sum = $a + $b;
    $html = "
       <div>
         <h1>sum a, b</h1>
         Number a is $a, number b is $b<br>
         a+b equals <b>$sum<b>
       </div>
    ";
    echo $html;
}

This adds spaces to the generated html code but if you use mod_pagespeed or similar apache mods, your server will remove all unnecesary spaces.

You can use the same technique for multi-row sql queries:

function bar($sql, $id) {
    $q= "
       SELECT
         name
       , address
       , phone
       FROM users
       WHERE id = '$id' -- possible mysql inyection
       LIMIT 1
    ";
    $sql->query($q);
}

The code gains in readability. It has no impact in performance and you can comment compex SQL queries (with # or --)

1
  • 2
    The downside to this approach is that double quotes must be escaped.
    – Tag
    Commented Oct 27, 2014 at 22:28
0

I wrote a function that allows you to indent as you wish. It's actually a pretty simple function. https://github.com/chiedolabs/moon-walk-php

I like it because my code stays clean this way.

2
  • Can I ask you to review the following meta post please? How to offer personal open-source libraries? Commented Dec 13, 2015 at 12:06
  • 3
    The With moonwalk: example on your GitHub page is malformed. The closing tag for the HEREDOC must appear at the beginning of the line, indentation is not possible. Commented Nov 9, 2016 at 10:53

Not the answer you're looking for? Browse other questions tagged or ask your own question.