3

I am trying to echo a string from a Recursive function:
echo "<li>", $node, recurse($arr), "</li>";
and
echo "<li>" . $node . recurse($arr) . "</li>";

function writeList($tree)
{
    if($tree == null) return;
    echo "<ul>";
    foreach($tree as $node=>$children) {
        echo "<li>", $node, writeList($children) , "</li>";
    }
    echo "</ul>";
}

$tree is a tree-like structure, as can be found in this question (form2)

And, I can notice that the output from the two is different.
Can someone tell me the difference in using , and . in general, and particularly, in this example?

EDIT: what if rather than echoing the strings, I want to store the string generated from this function in a variable. I am, particularly, interested in the output received from the first echo statement.

EDIT: I am feeding this array:

array
  3 => 
    array
      4 => 
        array
          7 => null
          8 => 
            array
              9 => null
      5 => null
  6 => null

The outputs I am getting is:
(from first echo statement)

<ul><li>3<ul><li>4<ul><li>7</li><li>8<ul><li>9</li></ul></li></ul></li><li>5</li></ul></li><li>6</li></ul>

(from second echo statement)

<ul><ul><ul><li>7</li><ul><li>9</li></ul><li>8</li></ul><li>4</li><li>5</li></ul><li>3</li><li>6</li></ul>
Community
  • 1
  • 1
Stoic
  • 10,536
  • 6
  • 41
  • 60
  • How can they differ? Everything would be treated as a string before being echoed out... – BoltClock Dec 08 '10 at 23:34
  • I have provided the function I am using, the input array and the outpur for two cases. Just tell me, its not an error on my side and rather a conceptual issue. :) – Stoic Dec 08 '10 at 23:50

2 Answers2

5

EDIT: OK, I get it. The culprit is your writeList() function. There is a secondary echo inside that function.

When you do this:

echo "<li>", $node, writeList($arr), "</li>";

Each part is evaluated first and then printed out. It is equivalent to:

echo "<li>";
echo $node;
echo writeList($arr);
echo "</li>";

But when you do this:

echo "<li>" . $node . writeList($arr) . "</li>";

The entire string is constructed using the concatenation operators . first, then printed out. This means writeList($arr) is called first during the construction of the string, then the outer echo is called.

To avoid this problem, don't echo anything within your function calls. Build strings using the concatenation operator and then return them so that your outer echo can print them.


what if rather than echoing the strings, I want to store the string generated from this function in a variable. I am, particularly, interested in the output received from the first echo statement.

Use output buffering.

ob_start();
echo "<li>", $node, writeList($arr), "</li>";
$out = ob_get_clean();

But for that particular statement, why not just concatenate instead?

$out = "<li>" . $node . writeList($arr) . "</li>";
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • I wanted to concatenate, as well. But, as I said, the two outputs are different here. :( – Stoic Dec 08 '10 at 23:37
  • 1
    @Stoic: Paste the output in your question. – BoltClock Dec 08 '10 at 23:37
  • Have added the function, input and output for this. – Stoic Dec 08 '10 at 23:51
  • So, the thing is that in the first evaluation occurs first and replaced one by one with function call, while in second string is constructed by calling recurse function, which rather than forming the string are actually echoing it at every level... right? – Stoic Dec 09 '10 at 00:05
2

echo is a language construct and can accept multiple arguments separated by a comma. The effect is identical to a concatenated string.

The output shouldn't be different - I can't think of an instance where it could be.

Edit: Ah, but it is. That is because your function echo()es stuff. In the first instance, <li> and $node get output; then the function's output comes.

I would have WriteList simply return values recursively.

Pekka
  • 442,112
  • 142
  • 972
  • 1,088
  • 2
    I'm thinking of things like what kind of output is generated by that function call, but no dice. `echo` inside that function doesn't return anything that could be accidentally echoed by the outer echo. – BoltClock Dec 08 '10 at 23:39
  • Wait, I think I nailed it; see my answer. – BoltClock Dec 09 '10 at 00:02
  • @BoltClock yeah, I added the same thing just now :) – Pekka Dec 09 '10 at 00:03