php暂停循环,在特定数量的递归循环后,PHP停止执行

我遇到的问题很奇怪。 在执行递归循环时会发生这种情况。 使用for循环或任何其他迭代执行相同任务时,不会发生这种情况。

在?21 000次以下递归调用函数时,一切正常。 超过此数字时会出现问题。

我的工作代码:

foo();

function foo($i = 1) {

if ($i > 20000) {

return;

}

echo $i . '
';

foo($i + 1);

return;

}

输出:... 199981999920000

不起作用的代码:

foo();

function foo($i = 1) {

if ($i > 30000) {  // Or any number above ~21000

return;

}

echo $i . '
';

foo($i + 1);

return;

}

输出:... 134931349413最后一行在数字中间停止。

在某些情况下,它只是向服务器发送一个空响应。

我正在PHP版本5.6.10的Ubuntu上使用apache2服务器。 使用Xampp时,会发生相同的问题,只是数字略有不同。

听起来像是内存问题。尝试更改最大内存设置,重新启动Apache,然后再次运行代码。

在现实生活中是否需要30K递归调用?听起来像简单的循环确实可以在这里更有效地解决问题。

每个脚本允许使用多少内存?我认为默认值为128,因此您可能需要将其更改为256甚至更高。检查您的PHP ini是否有" memory_limit"

增加xdebug.max_nesting_level。在此处检查答案stackoverflow.com/questions/17488505/

那执行时间呢?还是输出缓冲区?

调用堆栈也有限制

@kdlcruz我现在没有xdebug,所以不能成为问题

在将memory_limit设置为64M的情况下,我进入了278518。执行时间小于2秒。您是否尝试过使用error_reporting = E_ALL并观看error.log文件? (用于复制:哪个版本的ubuntu?)

@ frz3993 20000个循环的执行时间约为0.02秒。我认为那不是最糟糕的

@VolkerK Ubuntu版本是14.04.2 LTS。 Havent看了我的error.log。现在要做。

出于安全考虑:我的意思是在php.ini中由error_log=....指令指定的文件;-)

@VolkerK检查了error_log=...指定的我的文件,但其中没有任何相关内容。

我怀疑它停止在上述数字中间,仅打印13的原因是因为当您的代码以过多的递归溢出堆栈时,其余输出已被缓冲并且从未发送过。尝试在echo语句之后添加ob_flush()以获取完整的输出。

在大多数当前流行的编程语言(包括PHP)中,函数可以执行多少递归是有限制的。这不是硬性限制;根据程序的状态,可以递归调用数以万计的深度,也可以仅数个深度。因此,实现像示例这样的深度递归函数并不安全,并且程序将崩溃。请参阅PHP用户定义函数文档底部的注释:

Recursive function/method calls with over 100–200 recursion levels can smash the stack and cause a termination of the current script.

每次调用函数时,程序必须在开始执行该函数之前记录执行的位置,因此它知道在函数返回后再次从何处开始执行。存储此信息的空间非常有限,因此,如果您同时有太多的函数调用,它将耗尽空间,并且程序将崩溃。此信息以及大量其他信息都存储在堆栈中,当堆栈中的空间用完时,这称为堆栈溢出或粉碎堆栈。

某些语言实现了称为尾部调用优化的功能,该功能允许在适当的情况下进行无限递归。功能语言通常支持此功能,例如Scheme和ML。但是,如PHP是否优化尾部递归?中所述,PHP不能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值