耗尽内存 - 尝试修复循环,仍然不起作用

时间:2011-02-09 13:42:37

标签: php mysql memory memory-management

我目前遇到内存使用问题 - 但我无法弄清楚在哪里。我已经尝试用for循环替换我的一些foreach循环或者向DB发出另一个查询,但我仍然得到同样的错误 - “致命错误:允许的内存大小为134217728字节耗尽(试图分配72字节)in在第109行“。任何人都可以就可能导致问题的原因提供一些见解吗?谢谢!

@Patrick回答后的代码:

    $participating_swimmers = array();  
    $event_standings = array();
    $qualifying_times = array();

    $events = array();

        $current_event = '';
        $select_times_sql = "SELECT event, time, name, year, team, time_standard, date_swum
                            FROM demo_times_table
                            WHERE sex = 'M' AND (time_standard = 'A' OR time_standard = 'B')
                            ORDER BY event, time ASC";
        $select_times_query = mysql_query($select_times_sql);
        //Create array with the current line's swimmer's info
        while ($swimmer_info = mysql_fetch_assoc($select_times_query)) {
            if($current_event != $swimmer_info['event']){
                $events[] = $current_event = $swimmer_info['event'];
            }

            //Create array with the current line's swimmer's info
            $swimmer_info["time"] = $select_times_row['time'];
            $swimmer_info["name"] = $select_times_row['name'];
            $swimmer_info["year"] = $select_times_row['year'];
            $swimmer_info["team"] = $select_times_row['team'];
            $swimmer_info["time_standard"] = $select_times_row['time_standard'];
            $swimmer_info["date_swum"] = $select_times_row['date_swum'];

            //Create "Top 8" list - if more than 8 A cuts, take them all
            if (($swimmer_info["time_standard"] == "A") || ($swimmer_info["time_standard"] == "B")) {               
                //Check if there are 8 or less entries in the current event, or if the swim is an A cut
                if ((count($event_standings[$current_event]) < 8) || ($swimmer_info["time_standard"] == "A")) {
                    //Add swimmer to the list of invites
                    $event_standings[$current_event][] = $swimmer_info;

                    //Keep only the identifying information about the swimmer
                    $condensed_swimmer_info["name"] = $swimmer_info["name"];
                    $condensed_swimmer_info["year"] = $swimmer_info["year"];
                    $condensed_swimmer_info["team"] = $swimmer_info["team"];

                    //Check if swimmers name already appears in list
                    if (!in_array($condensed_swimmer_info, $participating_swimmers)) {
                        //It is a unique user - add them to the list
                        $participating_swimmers[] = $condensed_swimmer_info;
                    }
                } else {
                    //Add the qualifying time that did not fit into the list to a list of qualifying times
                    $qualifying_times[$current_event][] = $swimmer_info;    
                }
            }
        }

    //Sort each array of times in descending order

    arsort($event_standings);
    arsort($qualifying_times);
    $num_of_swimmers = count($participating_swimmers);

    while ($num_of_swimmers < 80) {
foreach ($events as $loe) {
    $num_of_qualifying_times = count($qualifying_times[$loe]);
    $swimmer_info = $qualifying_times[$loe][$num_of_qualifying_times-1];
    $event_standings[$loe][] = $swimmer_info;

     //Keep only the identifying information about the swimmer
    $condensed_swimmer_info["name"] = $swimmer_info["name"];
    $condensed_swimmer_info["year"] = $swimmer_info["year"];
    $condensed_swimmer_info["team"] = $swimmer_info["team"];            
    //Check if swimmers name already appears in list
    if (!in_array($condensed_swimmer_info, $participating_swimmers)) {
        //It is a unique user - add them to the list
        $participating_swimmers[] = $condensed_swimmer_info;
    }

    //Remove time from array of qualifying times
    unset($qualifying_times[$loe][$num_of_qualifying_times-1]);
}
$new_num_of_swimmers = count($participating_swimmers);
if($num_of_swimmers == $new_num_of_swimmers) break;
else $num_of_swimmers = $new_num_of_swimmers;
    }


    arsort($event_standings);
    arsort($qualifying_times);
    foreach($event_standings as $loe => $event_swimmer) {
    echo "<h1>",$loe,"</h1><br />"; 
    foreach ($event_swimmer as $es) {
        echo $es["time"],"  ",$es["name"],"  ",$es["team"],"<br />";
    }
    }

3 个答案:

答案 0 :(得分:1)

数据库中的大数据是95%的问题! - 尝试在查询中使用limit x,y,并将这些查询放在某个循环中。 - 请参阅http://php.net/manual/en/function.mysql-free-result.php可能有帮助

<?php

    $participating_swimmers = array();  
    $event_standings = array();
    $qualifying_times = array();

    $select_times_sql = "SELECT *
                        FROM demo_times_table
                        WHERE sex = 'M'
                        ORDER BY time ASC";
    $select_times_query = mysql_query($select_times_sql);
    while ($select_times_row = mysql_fetch_assoc($select_times_query)) {
        //Create array with the current line's swimmer's info
        $swimmer_info["time"] = $select_times_row['time'];
        $swimmer_info["name"] = $select_times_row['name'];
        $swimmer_info["year"] = $select_times_row['year'];
        $swimmer_info["team"] = $select_times_row['team'];
        $swimmer_info["time_standard"] = $select_times_row['time_standard'];
        $swimmer_info["date_swum"] = $select_times_row['date_swum'];

        //Create "Top 8" list - if more than 8 A cuts, take them all
        if (($swimmer_info["time_standard"] == "A") || ($swimmer_info["time_standard"] == "B")) {               
            //Check if there are 8 or less entries in the current event, or if the swim is an A cut
            if ((count($event_standings[$current_event]) < 8) || ($swimmer_info["time_standard"] == "A")) {
                //Add swimmer to the list of invites
                $event_standings[$current_event][] = $swimmer_info;

                //Keep only the identifying information about the swimmer
                $condensed_swimmer_info["name"] = $swimmer_info["name"];
                $condensed_swimmer_info["year"] = $swimmer_info["year"];
                $condensed_swimmer_info["team"] = $swimmer_info["team"];

                //Check if swimmers name already appears in list
                if (!in_array($condensed_swimmer_info, $participating_swimmers)) {
                    //It is a unique user - add them to the list
                    $participating_swimmers[] = $condensed_swimmer_info;
                }
            } else {
                //Add the qualifying time that did not fit into the list to a list of qualifying times
                $qualifying_times[$current_event][] = $swimmer_info;    
            }
        }
    }

    mysql_free_result($select_times_query);
    //Sort each array of times in descending order

    arsort($event_standings);
    arsort($qualifying_times);
    $num_of_swimmers = count($participating_swimmers);


        $sql = "SELECT DISTINCT(event)
                FROM demo_times_table
                WHERE sex = 'M' limit 80";
        $query = mysql_query($sql);
        while ($row = mysql_fetch_assoc($query)) {
            $loe = $row['event'];
            $num_of_qualifying_times = count($qualifying_times[$loe]);
            $event_standings[$loe][] = $qualifying_times[$loe][$num_of_qualifying_times-1];

             //Keep only the identifying information about the swimmer
            $condensed_swimmer_info["name"] = $qualifying_times[$loe][$num_of_qualifying_times]["name"];
            $condensed_swimmer_info["year"] = $qualifying_times[$loe][$num_of_qualifying_times]["year"];
            $condensed_swimmer_info["team"] = $qualifying_times[$loe][$num_of_qualifying_times]["team"];            
            //Check if swimmers name already appears in list
            if (!in_array($condensed_swimmer_info, $participating_swimmers)) {
                //It is a unique user - add them to the list
                $participating_swimmers[] = $condensed_swimmer_info;
            }

            //Remove time from array of qualifying times
            unset($qualifying_times[$loe][$num_of_qualifying_times-1]);
        }
        $num_of_swimmers = count($participating_swimmers);
        mysql_free_result($query);


    arsort($event_standings);
    arsort($qualifying_times);
    $sql = "SELECT DISTINCT(event)
                FROM demo_times_table
                WHERE sex = 'M'";
    $query = mysql_query($sql);
    while ($row = mysql_fetch_assoc($query)) {
        $loe = $row['event'];
            echo "<h1>".$loe."</h1><br />"; 

            foreach ($event_standings[$loe] as $es) {
                echo $es["time"]."  ".$es["name"]."  ".$es["team"]."<br />";
            }
    }

    /*
    foreach ($participating_swimmers as $ps) {
        echo $ps["name"]."<br /><br />";    
    }
    echo "<br /><br />";
*/
?>

答案 1 :(得分:0)

不是在查询中进行查询,而是可能存在创建永无止境循环的逻辑漏洞,您可以将其压缩为单个查询。对于你的第一个阻止,两个循环只是检查当前事件和参与者的性别,对吧?所以:

$result = SELECT * FROM <my database> WHERE sex = 'M' ORDER BY time ASC

然后你可以在while($ row = mysql_fetch_assoc($ result))循环中拉出你想要的任何行,并以另一种方式补偿非不同的值。

永无止境循环的另一个来源可能在您对排位时间进行排序的区块中。你在每次之后使用“unset”,这可能会使指针卡住。您可以尝试在取消设置后添加array_values($ qualifying_times)以重新索引数组。

答案 2 :(得分:0)

Frist off,丢失了SELECT DISTINCT,如下:

$events = array()

$current_event = '';
$select_times_sql = "SELECT event, time, name, year, team, time_standard, date_swum
                    FROM demo_times_table
                    WHERE sex = 'M' AND (time_standard = 'A' OR time_standard = 'B')
                    ORDER BY event, time ASC";
$select_times_query = mysql_query($select_times_sql);
//Create array with the current line's swimmer's info
while ($swimmer_info = mysql_fetch_assoc($select_times_query)) {
    if($current_event != swimmer_info['event']){
        $events[] = $current_event = $swimmer_info['event'];
    }
//Create "Top 8" list - if more than 8 A cuts, take them all
//Check if there are 8 or less entries in the current event, or if the swim is an A cut

这也会丢失一些冗余代码,并且可以加速最终输出(注意echo语句中的逗号 - 字符串在吐出之前不需要连接)

foreach($event_standings as $loe => $event_swimmer) {
    echo "<h1>",$loe,"</h1><br />"; 
    foreach ($event_swimmer as $es) {
        echo $es["time"],"  ",$es["name"],"  ",$es["team"],"<br />";
    }
}

最后一个问题在于第二个while循环,其中放入$ condensed_swimmer_info的信息没有-1,因此总是空白,$ num_of_swimmers永远不会超过其原始值:

while ($num_of_swimmers < 80) {
    foreach ($events as $loe) {
        $loe = $row['event'];
        $num_of_qualifying_times = count($qualifying_times[$loe]);
        $swimmer_info = $qualifying_times[$loe][$num_of_qualifying_times-1];
        $event_standings[$loe][] = $swimmer_info;

         //Keep only the identifying information about the swimmer
        $condensed_swimmer_info["name"] = $swimmer_info["name"];
        $condensed_swimmer_info["year"] = $swimmer_info["year"];
        $condensed_swimmer_info["team"] = $swimmer_info["team"];            
        //Check if swimmers name already appears in list
        if (!in_array($condensed_swimmer_info, $participating_swimmers)) {
            //It is a unique user - add them to the list
            $participating_swimmers[] = $condensed_swimmer_info;
        }

        //Remove time from array of qualifying times
        unset($qualifying_times[$loe][$num_of_qualifying_times-1]);
    }
    $new_num_of_swimmers = count($participating_swimmers);
    if($num_of_swimmers == $new_num_of_swimmers) break;
    else $num_of_swimmers = $new_num_of_swimmers;
}