【问题标题】:Memory leak in recursive function with reference递归函数中的内存泄漏与引用
【发布时间】:2016-03-15 19:19:22
【问题描述】:

我得到了以下代码。这是一个获取项目的系统以及项目的孩子的孩子的所有孩子。好吧,我使用递归函数来做到这一点:

<?php

header('Content-type: application/json; charset=UTF-8');

require_once 'config.php';

function getItems($parent) {
    global $db;

    $itemsStmt = $db->prepare('SELECT * FROM `items` WHERE `parent_id` = ?');
    $itemsStmt->execute(array($parent));
    return $itemsStmt->fetchAll(PDO::FETCH_ASSOC);
}

function addToArray($items, &$array) {    
    foreach ($items as $item) {
        $child = $item['child_id'];
        $indexer = $item['id'];

        $array[$indexer] = array('children' => array());
        $array[$indexer]['definition'] = $item;

        if ($child)
        {
            addToArray(getItems($child), $array[$indexer]['children']);
        }
    }
}

$array = array();

addToArray(getButtons(1), $array);

echo json_encode($array);

项目表如下所示:

id INT PK AI
title VARCHAR(100) NOT NULL
child_id INT
parent_id INT

child_id 用于孩子的 parent_id(因此,如果孩子不存在,您不必使用查询来获取孩子)。

现在,它有点工作。但是如果我添加一个包含以下数据的项目:

NULL
DELETEMELATER
0
2

我收到内存限制错误:

<b>Fatal error</b>:  Allowed memory size of 536870912 bytes exhausted (tried to allocate 42 bytes)

这一行是什么:

return $itemsStmt->fetchAll(PDO::FETCH_ASSOC);

【问题讨论】:

  • 当你调用getButtons时你的第一个函数被调用getItems
  • 抱歉忘记改了。但它仍然会发生。
  • parent_id 属于父级的id 列还是child 列?如果是id,您需要将getButtons($child) 更改为getButtons($indexer)
  • 我已经知道问题所在了。在我保存的 .php 文件中,我将 ID 1 的 child_id 更改为 1。 Parent_id 1 是组。因此,当循环 id 为 1 的项目时,它将再次添加父母和所有孩子。一遍又一遍,因为 parent_id 1 是组,并且都有孩子。 ID 1 是一个孩子。只是我的一个愚蠢的错误。
  • 你能增加你服务器的 php.ini 中的 memory_limit 吗?对于单个脚本,您可以使用: ini_set('memory_limit' '-1')

标签: php recursion memory-leaks


【解决方案1】:

我猜你的问题出在你的数据库 structure 和它的 dataparent_idchild_id 上,如果会有一行具有相同的 parent_id 和 child_id 你将有无限递归循环,这就是为什么您出现内存不足异常的原因,您必须修复数据库中的数据或升级表结构以仅具有 parent_id 并使用它来控制您的结构

数据库结构案例中的无限循环示例

1) item1 的父项是 item2,item2 的子项是 item1

2) 如果 item2 是 item1 的父项,而 item1 是 item3 的父项,但 item3 是 item2 的父项

【讨论】:

  • 是的,我发现了。只是我的一个愚蠢的错误。
猜你喜欢
  • 2012-10-31
  • 2013-06-15
  • 2012-08-31
  • 1970-01-01
  • 2021-07-11
  • 2017-05-09
  • 1970-01-01
  • 2014-12-21
  • 1970-01-01
相关资源
最近更新 更多