函數在自身內部直接或間接調用自身稱為遞歸。適用於樹形結構遍歷、分治算法、數學遞歸定義(如階乘、斐波那契)等場景。
<?php
function test() {
static $dig = 0;
if ($dig++ < 10) {
echo $dig;
test();
}
}
test(); // 輸出 12345678910
<?php
// 循環實現
function unreverse($str) {
for ($i = 1; $i <= strlen($str); $i++) {
echo substr($str, -$i, 1);
}
}
unreverse("abcdefg"); // gfedcba
// 遞歸實現
function reverse($str) {
if (strlen($str) > 0) {
reverse(substr($str, 1));
echo substr($str, 0, 1);
}
}
reverse("abcdefg"); // gfedcba
<?php
// 遞歸獲取所有子角色 ID 字符串
function explodeRole($roleObj, &$resultStr) {
if (count($roleObj->childRoleObjArr) > 0) {
foreach ($roleObj->childRoleObjArr as $child) {
$resultStr .= (empty($resultStr) ? '' : ', ') . $child->id;
explodeRole($child, $resultStr);
}
}
}
// 遞歸構建級聯角色關係數組
function makeRoleRelation(&$roleObjArr) {
foreach ($roleObjArr as &$item) {
$item->childRoleObjArr = getRoleObjArrByParentId($item->id);
if (count($item->childRoleObjArr) > 0) {
makeRoleRelation($item->childRoleObjArr);
}
}
}
function getRoleObjArrByParentId($parentId) {
// 假設使用某 ORM 查詢
$role = new COGPSTRTSysRole();
$role->setWhere("parentroleid=$parentId");
return $role->selectTable();
}
| 維度 | 遞歸 | 循環 |
|---|---|---|
| 可讀性 | 邏輯清晰,贴近數學定義 | 需手動維護棧/隊列,代碼較長 |
| 性能 | 函數調用開銷大,深度過大致棧溢出 | 無調用開銷,內存可控 |
| 適用場景 | 樹/圖遍歷、分治、回溯 | 線性迭代、已知次數循環 |
if ($depth > 1000) return; 防止棧溢出。