首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 遞歸函數使用示例與最佳實踐

     編輯:PHP 綜合知識

遞歸基本概念

函數在自身內部直接或間接調用自身稱為遞歸。適用於樹形結構遍歷、分治算法、數學遞歸定義(如階乘、斐波那契)等場景。

示例 1:靜態變量計數遞歸

<?php
function test() {
    static $dig = 0;
    if ($dig++ < 10) {
        echo $dig;
        test();
    }
}
test(); // 輸出 12345678910

示例 2:字符串逆序——循環 vs 遞歸

<?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();
}

遞歸 vs 循環:選擇建議

維度遞歸循環
可讀性邏輯清晰,贴近數學定義需手動維護棧/隊列,代碼較長
性能函數調用開銷大,深度過大致棧溢出無調用開銷,內存可控
適用場景樹/圖遍歷、分治、回溯線性迭代、已知次數循環

優化技巧

  • 尾遞歸優化: PHP 不支持,但可改寫為迭代。
  • 記憶化: 對重複子問題緩存結果(如斐波那契)。
  • 設置最大深度保護: if ($depth > 1000) return; 防止棧溢出。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved