我遇到的問題很奇怪。 在執行遞歸循環時會發生這種情況。 使用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不能。