nixp.ru v3.0

19 апреля 2024,
пятница,
08:06:42 MSK

n0xi0uzz написал 25 августа 2004 года в 10:16 (980 просмотров) Ведет себя как мужчина; открыл 13 тем в форуме, оставил 33 комментария на сайте.

Начал писать свой форум на перл. Естественно, по ходу возникает очень много вопросов и проблем. Что-то пытаюсь решить сам, но возникают такие проблемы, решение которых я сам найти не могу.

Вот первый из них:

При открытии топа из раздела, выводятся сообщения в этом топе. Проблема в следующем — я не могу сделать так, чтобы сообщения выводились с первого до последнего (т.е. первое — самое верхнее, последнее — самое нижнее), как принято во многих форумах, в данный момент сообщения выводятся наоборот. Ниже даю код и надеюсь на вашу помощь:

if (($sect ne "") and ($id ne ""))
{
 open $AT, "sections/$sect/$id.top";
 @ATtheme = <$AT>;
 close $AT;
 for ($AT1= 0; $AT1< @ATtheme; $AT1++)
 {
  @ATtheme1[$AT1]= @ATtheme[@ATtheme- $AT1- 1];
 }
 #постраничный вывод:
 $ATpages= int((@ATtheme- 1)/ 10);
 $Tpage= 0 if ($Tpage< 0) or ($Tpage> $ATpages) or ($Tpage ne int($Tpage));
 print "


<table>
<tr>
<td>
<center>\n»;

if ($ATpages> 0)

{

print «Страницы: »;

for ($ATtemp= 0; $ATtemp<= $ATpages; $ATtemp++)

{

print »».($ATtemp+ 1)."</A> » if ($Tpage ne $ATtemp);

print »».($ATtemp+ 1).«</B>\n» if ($Tpage eq $ATtemp);

}

}

print »

Назад в раздел</a></center></td></tr>»;

#

for ($i= $Tpage* 10; ($i< ($Tpage+ 1)* 10) and (@ATtheme1[$i]); $i++)

{

($ATaut, $ATTheme, $ATmsg, $ATtime) = split(/;;;;;/, @ATtheme1[$i]);

#Вывод непосредственно, сообщения ;)

print »
<table>
<tr>
<td>
<table align=«center» width=«65%»>
<tr>
<td>автор: $ATaut

Тема сообщения:$ATTheme</b>

сообщение добавлено <strong>$ATtime</b></td></tr></strong>
</td>
</tr>
<tr>
<td>$ATmsg</td></tr></table></td></tr>»;

}

}
</td>
</tr>
</table>
</td>
</tr>
</table>
</center>
</td>
</tr>
</table>

Genie

ну, проще, видимо, сделать первым поле «Время», тогда сортировать можно.

а так.. если сообщения добавляются в порядке поступления, т.е. последние в конец, то будет достаточно заменить:

for ($AT1= 0; $AT1< @ATtheme; $AT1++)
 {
  @ATtheme1[$AT1]= @ATtheme[@ATtheme- $AT1- 1];
 }


на:

@ATtheme1=reverse @ATtheme;

кроме того, тут вроде как ошибка есть. размер массива — это скаляр массива. т.е. надо

@ATtheme1[$AT1]= @ATtheme[$ATtheme- $AT1- 1];

но, как уже сказал, изящнее использовать reverse.

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

n0xi0uzz
Genie
кстати, при количестве сообщений в пару тысяч и файликом в несколько мегабайт это дело будет жутко тормозить. особенно при многочисленном обращении.

MySQL предлагаешь использовать?

Genie

ну, необязательно именно mySQL. но базу данных — это точно.

хотя, как я уже сказал, это только если нагрузка большая.

n0xi0uzz

ОК, спасиб за ответы.

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

Genie

придуманное одним для шифрования может быть придумано как расшифроват другим…

так что, видимо, в этом плане cookie надёжнее.

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

с другой стороны, можно сделать оба варианта и проверять на возможность использования cookie.

n0xi0uzz

В общем, возникла проблемка при выводе топиков из раздела.

В данный момент мой код выводит топики с последнего_добавленного да первого_добавленного, то есть, последний добавленный топ получается внизу, а мне надо наоборот и я не знаю, как это сделать =(

Плюс к этому, хочется к этой части кода добавить постраничный вывод, на каждой странице — по 10 топиков.

Ниже прилагаю нынешний код. Надеюсь на вашу помощь.

if (($sect ne "") and ($id eq "") and ($Tpage eq "") and ($act eq ""))
{
#считаем кол-во топиков в теме
$b= 0;
while (open $a, "sections/$sect/$b.top")
{
close $a;
$b++;
}
print "


<table>
<tr>
<td>
<center>Всего тем в разделе: », $b, «\n»;

print »

Назад на главную</a></center></tr></td>\n»;

#выводим все темы из раздела:

for ($a= 0; $a< $b; $a++)

{

open OTN, «sections/$sect/$a.top»;

@a= ;

$NumStr = @a; #кол-во строк в файле ;))

close OTN;

($Taut, $Ttheme, $Tmsg, $Ttime) = split(/;;;;;/, $a[0]);

($LTaut, $LTtheme, $LTmsg, $LTtime) = split(/;;;;;/, $a[@a-1]);

$NumAns = $NumStr -1; #Кол-во ответов на тему

print »

Заранее благодарен.
<table>
<tr>
<td>
<center>$Ttheme</a>

\n»;

print «Тему создал $Taut</a> в $Ttime

\n»;

#Выводим кол-во ответов:

if ($NumAns != 0)

{

print «Кол-во ответов: $NumAns

»;

}else

{

print «Тема пока что без ответов

»;

}

print «(Последнее сообщение добавил: $LTaut</a> в $LTtime)</center></tr></td>\n»;

}

}
</center>
</td>
</tr>
</table>
</center>
</td>
</tr>
</table>

Дмитрий Шурупов

И какое затруднение в обратном for?

for ($a= 0; $a< $b; $a++)

меняем на:

for ($a=$b; $a>0; $a--)

Ну, а постранично…

Пусть $page — страница, а $perpage — кол-во тем на странице. Тогда меняем еще раз for на:

for ($a=$page*$perpage; $a>($page-1)*perpage; $a--)

n0xi0uzz
SHuRuP
И какое затруднение в обратном for?

for ($a= 0; $a< $b; $a++)

меняем на:

for ($a=$b; $a>0; $a--)

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

SHuRuP
Ну, а постранично…

Пусть $page — страница, а $perpage — кол-во тем на странице. Тогда меняем еще раз for на:

for ($a=$page*$perpage; $a>($page-1)*perpage; $a--)

тоже не работает, я задаю

$perpage = 10;
$page=0;
for ($a=$page*$perpage; $a>($page-1)*$perpage; $a--)
 {
#действия
}

Этот предложенный тобой код выводит на странице раздела 10 тем, когда их там всего 2, причем первая — нормальная (стоит выше всех, она не «перевернулась»), а остальные 9 — пустые (без названия, кол-ва ответов и т.д.), вторая тема из раздела куда-то пропала…

Genie

ну, начнём…

#считаем кол-во топиков в теме

$b= 0;

while (open $a, «sections/$sect/$b.top»)

{

close $a;

$b++;

}

print »

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

while (-f "sections/$sect/$b.top")

но это не есть оптимальный, опять же, вариант. для получения имён в каталоге есть readdir(…). получится список файлов, определить его длину — одна строчка. ;)

кроме того, вот в этом месте

#выводим все темы из раздела:

for ($a= 0; $a< $b; $a++)

{

open OTN, «sections/$sect/$a.top»;

@a= ;

$NumStr = @a; #кол-во строк в файле ;))

close OTN;


файлы читаются в алфавитном порядке. что, наверное, не хотелось бы, да?

поэтому надо немного объединить эти два кода:

# определяем все имена фалов топиков
if (!opendir DIR, "sections/$sect")
{
    print "Error opening dir\n"; exit;
}
@fnames = sort grep (/\.top$/, readdir DIR); # нам надо только *.top
closedir DIR;
#считаем кол-во топиков в теме
$b=@frnames;
print "

<table>
<tr>
<td>
<center>Всего тем в разделе: », $b, «\n»;</center>
</td>
</tr>
<tr>
<td>
<center>Всего тем в разделе: $b\n»;

print »

Назад на главную</a></center></tr></td>\n»;

#выводим все темы из раздела:

for each $a (reverse @fnames)

{

open OTN, «sections/$sect/$a»;

@a= ;

$NumStr = @a; #кол-во строк в файле ;))

close OTN;


</center>
</td>
</tr>
</table>

n0xi0uzz

Огромное спасибо за помощь.

Но на всякий случай я уточню — итоговый код такой?

if (($sect ne "") and ($id eq "") and ($Tpage eq "") and ($act eq ""))
{
#считаем кол-во топиков в теме
if (!opendir DIR, "sections/$sect")
{
    print "Error opening dir\n"; exit;
}
@fnames = sort grep (/\.top$/, readdir DIR); # нам надо только *.top
closedir DIR;
#считаем кол-во топиков в теме
$b=@frnames;
print "


<table>
<tr>
<td>
<center>Всего тем в разделе: $b\n»;

print »

Назад на главную</a></center></tr></td>\n»;

#выводим все темы из раздела:

foreach $a (reverse @fnames)

{

open OTN, «sections/$sect/$a»;

@a= ;

$NumStr = @a; #кол-во строк в файле ;))

close OTN;

($Taut, $Ttheme, $Tmsg, $Ttime) = split(/;;;;;/, $a[0]);

($LTaut, $LTtheme, $LTmsg, $LTtime) = split(/;;;;;/, $a[@a-1]);

$NumAns = $NumStr -1; #Кол-во ответов на тему

print »
<table>
<tr>
<td>
<center>$Ttheme</a>

\n»;

print «Тему создал $Taut</a> в $Ttime

\n»;

#Выводим кол-во ответов:

if ($NumAns != 0)

{

print «Кол-во ответов: $NumAns

»;

}else

{

print «Тема пока что без ответов

»;

}

print «(Последнее сообщение добавил: $LTaut</a> в $LTtime)</center></tr></td>\n»;

}

}
</center>
</td>
</tr>
</table>
</center>
</td>
</tr>
</table>

Genie

ну, я бы ещё вот это:

#Выводим кол-во ответов:
if ($NumAns != 0)
{
print "Кол-во ответов: $NumAns
";
}else
{
print "Тема пока что без ответов
";
}


написал бы так:

#Выводим кол-во ответов:
print ($NumAns?"Кол-во ответов: $NumAns
":"Тема пока что без ответов
");


но это уже мелкие отпимизации… :))

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

n0xi0uzz

нет, выдает ошибку 500… ничего понять не могу, вроде все правильно…

Genie

вообще странно..

перезапуск сервера не помогает?

n0xi0uzz

Нет

Genie

очень странно…

давай в аську, там пообсуждаем.

надо будет ещё и полный исходник, чтобы это проверить у меня…

в общем, там определимся.

Последние комментарии

ecobeingecobeing.ru
Экология и вегетарианство на благо всем живым существам Планеты.