【问题标题】:Allowed memory size exhausted with recursive function递归函数耗尽允许的内存大小
【发布时间】:2016-01-22 15:59:11
【问题描述】:

作为尝试捕获同一用户的多个帐户的一部分,我们在用户登录时放置了一个 cookie。在登录期间,首先我们尝试读取以前的 cookie 并将其替换为新的。读取和写入的 cookie 存储在数据库中。在不删除 cookie 的情况下,该系统可以成为识别多帐户的一部分。

使用递归函数搜索多帐户时,内存不足。当不用作递归时,它可以工作,但有时一个用户有很多帐户,我们只能通过对所有找到的帐户重复此功能来找到它们。 重复此功能最多3次时有效,但可以肯定的是,此功能必须运行,直到找不到多帐户。

function xtest_getOtherNicks($dbh,$nick){
    /**
        Find all duplicate accounts, based on cookie
    */
    $aOtherNicks = array();
    $aCookies = db\ct_getCookies($dbh,$nick);

    foreach($aCookies as $k => $aCookie){

        $aFoundNicks = db\ct_getNick($dbh,$aCookies[$k]['cookiewaarde']);

        if(count($aFoundNicks) > 0){

            foreach($aFoundNicks as $key => $aFoundNick){

                if(!in_array($aFoundNick['nick'],$aOtherNicks)){
                    $aOtherNicks[] = $aFoundNick['nick'];

                    //Recursive part
                    //$aMoreFoundNicks = xtest_getOtherNicks($dbh,$aFoundNick['nick']);
                    /**
                    if(count($aMoreFoundNicks)>0){
                        foreach($aMoreFoundNicks as $key => $aMoreFoundNick){
                            if(!in_array($aMoreFoundNick['nick'],$aOtherNicks)){
                                $aOtherNicks[] = $aMoreFoundNick['nick'];
                            }    
                        }
                    } */

                }
            }
        }
    }

    return $aOtherNicks; 
}

我已经搜索过其他递归问题,但它们与我的不同。也许可以更改 SQL 并让数据库完成这项工作,但我对此一无所知。

表:

CREATE TABLE IF NOT EXISTS `cookietest` (
  `cookiewaarde` varchar(100) NOT NULL,
  `nick` varchar(100) NOT NULL,
  `datum` datetime NOT NULL,
  `rw` enum('r','w') NOT NULL,
  KEY `cookiewaarde` (`cookiewaarde`),
  KEY `nick` (`nick`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

cookie 查询:

$q = "SELECT 
            cookiewaarde
        FROM
            cookietest
        WHERE
            nick = '".sanitize($nick)."'";// will be converted to PDO

【问题讨论】:

    标签: php function recursion


    【解决方案1】:

    您需要将$aOtherNicks 传递到递归范围。否则你不会打破递归循环,因为它将与空数组进行比较(找到的值总是唯一的)。这应该工作:

    function xtest_getOtherNicks($dbh, $nick, $aOtherNicks = array())
    {
        $aCookies = db\ct_getCookies($dbh, $nick);
        foreach ($aCookies as $aCookie) {
    
            $aFoundNicks = db\ct_getNick($dbh, $aCookie['cookiewaarde']);
            foreach ($aFoundNicks as $aFoundNick) {
                if (in_array($aFoundNick['nick'], $aOtherNicks)) { continue; }
                $aOtherNicks[] = $aFoundNick['nick'];
                $aOtherNicks = xtest_getOtherNicks($dbh, $aFoundNick['nick'], $aOtherNicks);
            }
        }
    
        return $aOtherNicks;
    }
    

    【讨论】:

    • 非常非常感谢!尤其是解释为什么你的代码有效而我的无效。
    • @Terradon 递归函数(尤其是递归调用条件取决于当前状态的情况)在对象上下文(类语法)中更方便。不需要传递对象属性(包括 dbh),因为它与方法(类函数)具有相同的(对象)范围。
    猜你喜欢
    • 2020-11-20
    • 2020-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 2018-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多