有一个功能:
<?php
function test(){
static $count = 0;
$count++;
echo $count;
if ($count < 10) {
test();
}
$count--;
echo $count;
}
test();
?>
此代码生成:123456789109876543210
当$ count递增到10 - 这是可以理解的,它一直有效,直到if语句的计算结果为false。 但为什么它逐渐减少到0? 在我的新手逻辑中,$ count--在这段代码中应该只减少9次,并且函数应该停止。 没有循环或循环可以逐步降低其价值。但我们看到,它在这里工作。 为什么会这样?
答案 0 :(得分:2)
好的,所以我试着想象一下这里发生了什么,这样你就可以更好地了解发生了什么。
这就是发生的事情(摘要):
//Iteration 1
function(){
//Code before runs
if stmt (TRUE) //Iteration 2
function(); → function(){
←┐ //Code before runs
//Code after│
} │ if stmt (TRUE) //Iteration 10
│ function(); → ... → function(){
│ ←┐ //Code before runs
│ //Code after │
│ } │ if stmt (FALSE)
└──── ← function returns │
value and goes │ //Code after runs
back to next line │ }
└────── ← function returns value and goes back to next line
因此,在第10个函数调用中,if语句为FALSE且不再调用函数。
现在第10次调用函数运行到最后并减少变量。
它返回返回值(NULL)并返回上一个函数调用,该函数调用执行函数调用的其余部分,这也会减少变量,等等......
答案 1 :(得分:2)
当您将输出更改为强调条件递归调用的工作原理时,事情可能会更加清晰:
<?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();
打印
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
您的问题似乎是了解函数调用和函数后续返回的工作原理。让我们开始简单
<?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();
打印
a in
b in
c in
c out
b out
a out
很容易,不是吗?当函数退出/返回时,执行将继续执行调用。并且这不是函数的名称,而是函数调用本身,请参阅例如https://en.wikipedia.org/wiki/Call_stack。<?php
function foo($param) {
echo "foo($param) in", PHP_EOL;
if ( $param!==1 ) {
foo(1);
}
echo "foo($param) out", PHP_EOL;
}
foo(0);
不会导致单个退出/返回取消“相同”函数的所有函数调用,但它只会在调用堆栈中冒出一个“范围”/帧。因此输出
foo(0) in
foo(1) in
foo(1) out
foo(0) out
现在将其与上述“改进”脚本的输出进行比较:我希望能为您解决一些问题。