[php] утекает память.. непонятно где.

Phoenix


else if($action === "rp9a")
{
$users_online = users_online;
$out1="";
$out2="";

$out1.="<p>".$rep_name."</p>\r\n";
$res = mysql_query("SELECT t5.name, ".
" (SELECT COUNT(*) FROM garant_requests t3 ".
" INNER JOIN tasks t1 ON t3.tasks_id=t1.id AND t1.state<>'resolved' ".
" WHERE t1.responser=t5.garant_userlogin) ".
" AS task_in_work, ".
" (SELECT COUNT(*) FROM garant_requests t3 ".
" INNER JOIN taskmessage t4 ON t3.tasks_id=t4.task ".
" AND DATE(t4.`date`)=CURDATE ".
" AND t4.is_system=0 ".
" WHERE t4.reporter=t5.garant_userlogin) ".
" AS records, ".
" t5.garant_userlogin AS userlogin ".
" FROM users t5 ".
" WHERE t5.can_enter_inside = 1 ".
" AND t5.name LIKE 'Эксперт%' ".
" AND t5.name NOT LIKE '%НПП%' ".
" ORDER BY t5.name", $link);
if($res)
{
$num = mysql_num_rows($res);
if($num > 0)
{
$out1.="<p>Результат: ".$num."</p>\r\n";
$num = 0;
$sum = 0;
$count_online=0;
$count_offline=0;
if($get === "csv")
{
$out2.="\"Текущий ответственный\";".
"\"Число задач в работе\";".
"\"Число реплик\"\r\n";
}
else
{
$out2.="<table border=\"1\">\r\n<tr>".
"<td>#</td>".
"<td>Текущий ответственный</td>".
<td>Число задач в работе</td>".
"<td>Число реплик</td>".
"<td>Статус</td>".
"</tr>\r\n";
}
while($row = mysql_fetch_row($res
{
$out1.="<pre>";
$out1.=$num." ".memory_get_usage."\n";
$out1.="<pre>";
echo $out1;
$out1="";


$username=preg_replace("/^.*#/",'',$row[3]);

$status = is_online($username,$users_online,$count_online,$dir_lastvisit);



$num++;
if($get === "csv")
{
$out2.= "\"".csvjoin("\";\"", $row)."\"\r\n";
}
else
{
$out2.= "<tr>";
$out2.="<td>".$num."</td>";
$out2.="<td><a href=".HTTP_VIEWFOTO_PATH."/viewfoto.php?id=".$username.">".$row[0]."</a></td>";
$out2.="<td".(intval($row[1])?"":" bgcolor=\"lightgrey\"").">".$row[1]."&nbsp;</td>";
$out2.="<td".(intval($row[2])?"":" bgcolor=\"lightgrey\"").">".$row[2]."&nbsp;</td>";
$out2.='<td class="status">'.$status.'</td>';
$out2.="</tr>\r\n";

$sum += intval($row[1]);
}
}
$out2.="</table>\r\n";
$out1.="<p>Задач в работе: ".$sum."</p>\r\n";
$proc = round(100*$count_online/$num,2);
$out1.="<p>Пользователей ON LINE: ".$count_online.' / '.$num." ( ".$proc."% )</p>\r\n";

print $out1;
print $out2;

mysql_free_result($res);
}
else
{
echo "Совпадений не найдено!\r\n";
}
}
else
{
echo "mysql error: ".htmlspecialchars(mysql_error($link."\r\n";
}
}
else if($action === "rp9")
{
$out1="";
$out2="";

$users_online = users_online;
//$out1.="<pre>";
//$out1.=var_export($users_online,true);
//$out1.=memory_get_usage."\n";
//$out1.="<pre>";
//echo $out1;
//$out1="";

$out1.="<p>".$rep_name."</p>\r\n";


$res = mysql_query("SELECT t5.name, ".
" (SELECT COUNT(*) FROM garant_requests t3 ".
" INNER JOIN tasks t1 ".
" ON t3.tasks_id=t1.id AND t1.state<>'resolved' ".
" WHERE t1.responser=t5.garant_userlogin) ".
" AS task_in_work, ".
" (SELECT COUNT(*) FROM garant_requests t3 ".
" INNER JOIN taskmessage t4 ON t3.tasks_id=t4.task ".
" AND DATE(t4.`date`)=CURDATE ".
" AND t4.is_system=0 ".
" WHERE t4.reporter=t5.garant_userlogin) ".
" AS records, ".
" t5.garant_userlogin AS userlogin ".
" FROM users t5 ".
" WHERE t5.can_enter_inside = 1 ".
" AND t5.name LIKE 'Эксперт%' ".
" AND t5.name NOT LIKE '%НПП%' ".
" ORDER BY t5.name",
$link);

if($res)
{
$num = mysql_num_rows($res);
if($num > 0)
{
$out1.="<p>Результат: ".$num."</p>\r\n";
$num = 0;
$sum = 0;
$count_online=0;
if($get === "csv")
{
$out2.="\"Текущий ответственный\";".
"\"Число задач в работе\";".
"\"Число реплик\"\r\n";
}
else
{
$out2.="<table border=\"1\">\r\n<tr>".
"<td>#</td>".
"<td>Текущий ответственный</td>".
<td>Число задач в работе</td>".
"<td>Число реплик</td>".
"<td>Статус</td>".
"</tr>\r\n";
}
while($row = mysql_fetch_row($res
{
$out1.="<pre>";
$out1.=$num." ".memory_get_usage."\n";
$out1.="<pre>";
echo $out1;
$out1="";

$username=preg_replace("/^.*#/",'',$row[3]);

$status = is_online($username,$users_online,$count_online,$dir_lastvisit);


$num++;
if($get === "csv")
{
$out2.= "\"".csvjoin("\";\"", $row)."\"\r\n";
}
else
{
$out2.= "<tr>";
$out2.="<td>".$num."</td>";
$out2.="<td><a href=".HTTP_VIEWFOTO_PATH."/viewfoto.php?id=".$username.">".$row[0]."</a>&nbsp;</td>".
$out2.="<td".(intval($row[1])?"":" bgcolor=\"lightgrey\"").">".$row[1]."</td>";
$out2.="<td".(intval($row[2])?"":" bgcolor=\"lightgrey\"").">".$row[2]."</td>";
$out2.='<td class="status">'.$status.'</td>';
$out2.="</tr>\r\n";
$sum += intval($row[1]);
}
}
$out2.="</table>\r\n";
$out1.="<p>Задач в работе: ".$sum."</p>\r\n";
$proc = round(100*$count_online/$num,2);
$out1.="<p>Пользователей ON LINE: ".$count_online.' / '.$num." ( ".$proc."% )</p>\r\n";

print $out1;
print $out2;

mysql_free_result($res);
}
else
{
echo "Совпадений не найдено!\r\n";
}
}
else
{
echo "mysql error: ".htmlspecialchars(mysql_error($link."\r\n";
}
}


теперь то, что выводит блок

$out1.="<pre>";
$out1.=$num." ".memory_get_usage."\n";
$out1.="<pre>";
echo $out1;
$out1="";

при вызове с параметром rp9
0 545584
1 546344
2 549720
3 551400
4 554520
5 560824
6 573376
7 598520
8 648832
9 749392
10 952032
11 1354360
12 2159008
13 3768376
14 6988424
15 13425680
16 26300216
17 5204

sinet

после diff file1 file2 - я не нашёл
никаких отличий.
А они есть.
Во втором случае нет строчки: $count_offline=0;

Phoenix

она не используется :grin:
вряд ли пхп смог для неё выделить 50мегов

hashion

mysql_free_result($res) нужно делать даже если результата нет (нет строк).

Irina22

там память используемая по экспоненте расти начинает.
вряд это из-за того, что какую-то переменную забыли удалить.

kruzer25

1) У тебя говнокод.
2) Твой код - пиздец говно.
3) Ты что, серьёзно думал, что кто-то будет тут ковыряться в нескольких страницах твоего говна в попытке понять, что оно делает?
Если по теме - не верю, что весь этот твой код является минимальным, производящим эту ошибку. Очисти его до минимума, и после этого что-то спрашивай.

Irina22

я не прошу в нём разбираться.
я сказал, что два куска делают одно и тоже, что один кушает память в ожидаемый кол-вах, второй - в неожидаемых.
вопрос был не в том, что я прошу кого-нибудь там найти косяк, а в том, чтобы узнать идею, почему такое может быть. я с таким поведением столкнулся в первый раз.
код был дан лишь с целью ознакомления(какие функции используются и пр). о чём речь, т.к. если убрать его, первым же постом было бы
" ну ты бы хоть код свой показал :smirk: "

Vodnik

я тупо сделал дифф
эти два (ужасно кривых) куска кода неодинаковы
во второй части есть:
 

$out2.="<td><a href=".HTTP_VIEWFOTO_PATH."/viewfoto.php?id=".$username.">".$row[0]."</a>&nbsp;</td>".
$out2.="<td".(intval($row[1])?"":" bgcolor=\"lightgrey\"").">".$row[1]."</td>";

там точка в конце строки вместо ";" :) забавно :)

sinet

Точку я и не заметил. Думал оно на &nbsp; ругается. )

Dasar

там точка в конце строки вместо ";" забавно
а как это интерпретируется?

Irina22

про точку - спасибо. я это либо не заметил, либо просто запостил с ошибкой.
если косяк в этом, то очень странно, что оно работало без ошибок
$a .= "text1" . $a = "text2";
разве сначала присваивание, а потом конкатенация?
т.е. эквивалентно
$a .= $text1" . ($a = "text2");
?

artimon

Отсюда наверное и память растёт по экспоненте. У тебя длина строки удваиватся на каждом шаге.

Phoenix

ага.
это оно.
но непонятно всё равно, почему растёт память.

$teststr = "";

for($i=1;$i<10;$i++) {
$teststr = " test1 ". $teststr= " test2 ";
print $teststr."\n";

}

c:\home\igor\devel\etc>php aaa.php
test1 test2
test1 test2
test1 test2
test1 test2
test1 test2
test1 test2
test1 test2
test1 test2
test1 test2

UPD
зато в совокупности с ? "" :"fdsaf"; получили

for($i=1;$i<5;$i++) {
$b = rand(0,1);
$teststr .= " test1 ".
$teststr.= " test2 ". ($b==0) ? "" : "test3";
print "b: ".$b. " ". $teststr."\n";

}

c:\home\igor\devel\etc>php aaa.php
b: 0 test1
b: 1 test1 test1 test1
b: 0 test1 test1 test1 test1 test1 test1 test1
b: 0 test1 test1 test1 test1 test1 test1 test1 test1 test1 test1 test
1 test1 test1 test1 test1

в общем, опять подвела лень приводить код в порядок :(

Phoenix

собственно, раз уже назвали текст говном(мне он и самому не нравится
хочется услышать, что именно в нём не нравится.
глядишь, почерпну пару-тройку новых замечаний

Boris1980

Сам прикинь. У тебя $action "rp9a" отличается от "rp9" только sql выражением. А код полностью продублирован. В итоге получаешь на поддержку повторяющийся код. Через полгода всех таких мест не упомнишь, что при правке в одном месте нужно тоже самое поправить и в другом.
Щас тебе еще посоветуют определить все классами и методами, и весь твой экшн уложится в пять-десять красивых строк.

artimon

ты пропустил ещё одну точку.
$teststr .= " test1 ". $teststr= " test2 ";

iakobi91

в цикле присваивание замени на .=, отсюда и говно лезет

Irina22

:grin:

Irina22

Сам прикинь. У тебя $action "rp9a" отличается от "rp9" только sql выражением
это не в счёт, т.к. должен быть только один rp9.
интересно услышать по поводу того, что внутри if'ов
когда появляется время, я конечно, объединяю общие куски.
как мне объяснили, весь код писался в овральном режиме без каких-то планирований изменений в будущем, и самое главное сами изменения вносились на скорую руку, в результате, получилось то, что есть.

sinet

интересно услышать по поводу того, что внутри if'ов
По хорошему надо:
1) Функции работы с БД обернуть классом;
2) Вместо кусков кода $out2.= использовать какой-нибудь движок шаблонов.
Этот код сейчас не удобно ни читать, ни отлаживать, ни модифицировать.

Vodnik

разве сначала присваивание, а потом конкатенация?
оказывается да, сам удивился

sollariss

Например, Smarty
Оставить комментарий
Имя или ник:
Комментарий: