2011-02-09 2 views
1

В настоящее время я испытываю проблему с использованием памяти - но я не могу понять, где. Я попытался заменить некоторые из моих циклов foreach на петли или выдавать другой запрос в БД, но я все равно получаю ту же ошибку - «Неустранимая ошибка: допустимый размер памяти из 134217728 байт исчерпан (пытался выделить 72 байта) в на линии 109 ". Может ли кто-нибудь дать представление о том, что может вызвать проблему? Спасибо!Исчерпающая память - испробованные фиксирующие петли, все еще не работает

код после ответа @Patrick «s:

$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 />"; 
    } 
    } 
+0

В базе данных всего 606 единиц, поэтому количество предметов невелико. – Jim

+2

Вы пробовали быстрый и грязный 'ini_set ('memory_limit', '256M');'? – alex

+0

+1 для грязного метода, но если его база данных большая, ему требуется больше оперативной памяти. –

ответ

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 />"; 
*/ 
?> 
+0

У меня только 606 предметов в таблице - я бы не сказал, что это большой, не так ли? – Jim

+0

ответ обновлен, разве этот набор не будет больше когда-нибудь? –

+0

Это может сработать Ronan, теперь он пытается это сделать – Jim

0

Вместо того, чтобы делать запрос в запросе, с потенциалом для логических дыр, которые создают бесконечный цикл, вы можете уплотнить его в одном запросе. Для вашего первого блока оба цикла просто проверяют текущее событие и пол участника, не так ли? Итак:

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

Тогда вы можете вытащить строки в зависимости от того вы хотите во время ($ строка = mysql_fetch_assoc ($ результат)) петлю и компенсации без различных значений по-другому.

Еще один источник бесконечного цикла может быть в блоке, где вы сортируете квалификационные моменты. Вы используете «unset» после каждого, что может привести к тому, что указатель застрял. Вы можете попробовать добавить array_values ​​($ qualifying_times) после того, как unset переделает массив.

+0

TKM, ваше решение похоже на Ronan's - и пока оно еще не решило его. Я попытался добавить array_values, и это все еще не решает проблему (я все равно удаляю последний элемент из массива, поэтому я не понимаю, почему он должен был бы реорганизоваться сам, но я все равно оставил код). – Jim

0

Frist прочь, проиграть 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 

Это также теряет немного избыточного кода, и может ускорить окончательный вывод (обратите внимание на запятые в эхо-заявления - строка Безразлично» т должны быть сцеплены перед ее выплюнула)

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 />"; 
    } 
} 

Последняя проблема заключается в секунду в то время как цикл, где информация претворяются в $ condensed_swimmer_info не имеют -1 в месте, таким образом, всегда пустой , а $ num_of_swimmers никогда не поднимается до более чем 1 над его исходным значением:

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; 
} 
+0

У меня нет ничего в моей нынешней системе, чтобы проверить это, но это должно быть простым делом для решения любых оставшихся проблем. – Patrick

+0

Благодарим вас за ответ Патрик! Я поместил код в качестве редактирования в свой первый пост. он выводит имена событий, но не раз для событий. Я должен работать, но я проверю позже, чтобы узнать, где информация теряется. – Jim