Perhaps things get a bit clearer when you change the output to emphasis how the conditional recursive call works:
<?php
function test($level=0) {
static $count = 0;
$count++;
echo str_pad('a:', $level+2, ' ', STR_PAD_LEFT), $count, PHP_EOL;
if ($count < 10) {
test($level+1);
}
$count--;
echo str_pad('b:', $level+2, ' ', STR_PAD_LEFT), $count, PHP_EOL;
}
test();
prints
a:1
a:2
a:3
a:4
a:5
a:6
a:7
a:8
a:9
a:10
b:9
b:8
b:7
b:6
b:5
b:4
b:3
b:2
b:1
b:0
Your problem seems to be understanding how the function call(s) and subsequent return(s) from the function works. Let's start simple
<?php
function c() {
echo 'c in', PHP_EOL;
echo 'c out', PHP_EOL;
}
function b() {
echo 'b in', PHP_EOL;
c();
echo 'b out', PHP_EOL;
}
function a() {
echo 'a in', PHP_EOL;
b();
echo 'a out', PHP_EOL;
}
a();
prints
a in
b in
c in
c out
b out
a out
Easy enought, isn't it? When a function exits/returns the execution continues at the point where the call was made. And that isn't bound to the name of the function, but the function call itself, see e.g. https://en.wikipedia.org/wiki/Call_stack .
So even if a function calls itself like
<?php
function foo($param) {
echo "foo($param) in", PHP_EOL;
if ( $param!==1 ) {
foo(1);
}
echo "foo($param) out", PHP_EOL;
}
foo(0);
that doesn't cause a single exit/return to cancel all function calls of the "same" function, but it just bubbles up one "scope"/frame in the call stack. Therefore the output is
foo(0) in
foo(1) in
foo(1) out
foo(0) out
Now compare that to the output of the "improved" script above: I hope that clears things up a bit for you.