Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > сортировка массива с помощью krsort


Автор: Oughtem 4.2.2009, 01:26
 Прошу помощи знатоков. Есть некий плагин для некой КМС и некий файл этого плагина. Этот файл обрабатывает данные из базы и строит топ самых активных пользователей на сайте учитывая Дату Регистрации, кол-во комментариев, кол-во страниц, файлов и постов, определяя переменную "Рейтинг" и выводя таблицу с TOP10 юзеров

Сам файл вот (извиняюсь за простыню - спойлера не нашёл)

Код

<?PHP

/* ====================
Seditio - Website engine
Copyright Neocrome
http://www.neocrome.net

[BEGIN_SED]
File=plugins/activepanel/activepanel.php
Version=100
Updated=2007-sep-25
Type=Plugin
Author=faust64
Description=
[END_SED]

[BEGIN_SED_EXTPLUGIN]
Code=activepanel
Part=main
File=activepanel
Hooks=standalone
Tags=
Minlevel=0
Order=10
[END_SED_EXTPLUGIN]

==================== */
if (!defined('SED_CODE')) { die('Wrong URL.'); }

function count_val($sql_name, $field, $id)
{
        $count = 0;
        mysql_data_seek($sql_name, 0);
        while ($countrow = mysql_fetch_assoc($sql_name))
                {if ($countrow[$field] == $id){$count++;}}
        return $count;
}

function total_user_rating($page, $com, $posts, $pfs, $reg_date, $karma = 0, $medals = 0)
{
        $karma_div = ($karma != 0) ? 1 : 0;
        $medals_div = ($medals != 0) ? 1 : 0;
        $reg_time = (mktime(date(d),date(m),date(Y)) - $reg_date)/86400;
        $total = ($page/4 + $com/10 + $posts/8 + $pfs/10 + $karma + $medals)/(5 + $karma_div + $medals_div);
        return round($total, 2);
}

$ekarma = $cfg['plugin']['activepanel']['ekarma'];
$emedals = $cfg['plugin']['activepanel']['emedals'];
$max_list = $cfg['plugin']['activepanel']['max_list'];
$top_limit = $cfg['plugin']['activepanel']['top_limit'];

$sql = sed_sql_query("SELECT * FROM $db_users WHERE user_maingrp!='2' ORDER BY user_id");
$sql1 = sed_sql_query("SELECT com_authorid FROM $db_com");
$sql2 = sed_sql_query("SELECT page_ownerid FROM $db_pages");
$sql3 = sed_sql_query("SELECT pfs_userid FROM $db_pfs");

clearstatcache();

if (file_exists("plugins/karma/"))
        {
                $sql4 = sed_sql_query("SELECT karma_recipient FROM sed_karma");
                $f_karma = TRUE;
        }
else
        {$f_karma = FALSE;}

if (file_exists("plugins/medals/"))
        {
                $sql5 = sed_sql_query("SELECT medals_recipient FROM sed_medals");
                $f_medals = TRUE;
        }
else
        {$f_medals = FALSE;}

$colkarma = ($ekarma && $f_karma) ? "<td class='coltop'>".$L['karma']."</td>" : "";
$colmedals = ($emedals && $f_medals) ? "<td class='coltop'>".$L['medals']."</td>" : "";

$current = ($_GET['a']>0) ? $_GET['a'] : "0";
$next = $current + $max_list;
$prev = $current - $max_list;
$user_list .= "<table class='cells'>";
$user_list .= "<tr><td class='coltop'>".$L['uname']."</td><td class='coltop'>".$L['mngr']."</td><td class='coltop'>".$L['level']."</td><td class='coltop'>".$L['reg']."</td><td class='coltop'>".$L['com']."</td><td class='coltop'>".$L['page']."</td><td class='coltop'>".$L['pfs']."</td><td class='coltop'>".$L['post']."</td>".$colkarma.$colmedals."<td class='coltop'>".$L['rating']."</td></tr>";
$current_pos = 0;

while ($row = mysql_fetch_assoc($sql))
        {
                $current_pos++;
                if ($current_pos > $current && $current_pos <= $next)
                {
                        $user = sed_build_user($row['user_id'], sed_cc(stripslashes($row['user_name'])));
                        $mngrp = sed_build_group($row['user_maingrp']);
                        $mgrpstrs = sed_build_stars($sed_groups[$row['user_maingrp']]['level']);
                        $regdate = date("d.m.Y", $row['user_regdate']);
                        $comcount = count_val($sql1, "com_authorid", $row['user_id']);
                        $pagecount = count_val($sql2, "page_ownerid", $row['user_id']);
                        $pfscount = count_val($sql3, "pfs_userid", $row['user_id']);
                        $postcount = $row['user_postcount'];
                        $karma = ($ekarma && $f_karma) ? count_val($sql4,"karma_recipient",$row['user_id']) : "0";
                        $medals = ($emedals && $f_medals) ? count_val($sql5,"medals_recipient",$row['user_id']) : "0";
                        $rating = total_user_rating($pagecount, $comcount, $postcount, $pfscount, $row['user_regdate'], $karma, $medals);
                        $karma = ($ekarma && $f_karma) ? "<td>".$karma."</td>" : "";
                        $medals = ($emedals && $f_medals) ? "<td>".$medals."</td>" : "";
                        $user_array[$rating*100][$row['user_id']] = array("str" => "<tr><td>$user</td><td>$mngrp</td><td>$mgrpstrs</td><td>$regdate</td><td>$comcount</td><td>$pagecount</td><td>$pfscount</td><td>$postcount</td>".$karma.$medals."<td>$rating</td></tr>", "user" => $user);
                }
        }

krsort($user_array);


foreach($user_array as $k)
        {
                foreach($k as $i)
                        {
                                $user_list .= $i['str'];
                                if ($topcount < $top_limit){$top[] = $i['user'];}
                                $topcount++;
                        }
        }
       
$user_list .= "</table>";

$top_list = implode(', ', $top);
$prev_link = ($current > 0) ? "<a href='plug.php?e=activepanel&a=".$prev."'><<< ".$L['prev'].$max_list."</a>" : "";
$next_link = ($current < $current_pos-$max_list) ? "<a href='plug.php?e=activepanel&a=".$next."'>".$L['next'].$max_list." >>></a>" : "";
?>



Всё считает, обрабатывает, но...
В этом фале работает функция krsort($user_array), и работает коряво - она должна выводить сортировку по рейтингу, а выводит сортировку по дате регистрации юзера. Оч. прошу, подскажите, где подкрутить, чтоб сортировало по рейтингу - его же высчитываем.

Заранее спасибо.

Автор: ViniPuh 4.2.2009, 08:28
krsort делает далеко не то что вам нужно.
krsort — Отсортировать массив по ключам в обратном порядке
Документация: http://www.php.net/manual/ru/function.krsort.php

Вам скорее всего нужны: http://www.php.net/manual/ru/function.uasort.php или http://www.php.net/manual/ru/function.usort.php. Там есть описание и примеры.


Автор: Oughtem 4.2.2009, 09:18
хм... так мне же и надо отсортировать по ключу в обратном порядке, т.е., чтоб сверху были те, у кого рейтинг выше. Или я вас не правильно понял?

Автор: ksnk 4.2.2009, 09:38
Oughtem, Нужно ответить себе на вопрос. В какое место уходят индексы MySql, если данные уже прочитаны и переложены в массив PHP. 
После этого почитать про другие методы сортировки...
хотя, полезнее, для этой задачи, почитать про SQL...

Автор: Oughtem 4.2.2009, 09:55
Цитата

После этого почитать про другие методы сортировки...

ksnk, я попробовал  uasort, usort, uksort. Работает, сортирует по рейтингу, но везде ругается на значение ключа функции (как я понял) 

Warning: Wrong parameter count for uksort() in ..../activepanel.inc.php on line 108

line 108 это 
Код
krsort($user_array);


что-то не правильно...

Автор: skyboy 4.2.2009, 10:42
Цитата(Oughtem @  4.2.2009,  08:55 Найти цитируемый пост)
но везде ругается на значение ключа функции (как я понял) 

нет. смотри документацию по http://php.net/ksort и http://php.net/uksort
И ksort, и uksort принимают по два аргумента.
И РНР именно это и говорит:
Цитата(Oughtem @  4.2.2009,  08:55 Найти цитируемый пост)
Warning: Wrong parameter count for uksort()

Цитата

Неверное количество параметров для uksort()

Цитата(ViniPuh @  4.2.2009,  07:28 Найти цитируемый пост)
krsort — Отсортировать массив по ключам в обратном порядке

дык, у него индексом выступает как раз рейтинг:
Цитата(Oughtem @  4.2.2009,  00:26 Найти цитируемый пост)
 $user_array[$rating*100][$row['user_id']] = array("str" => "<tr><td>$user</td><td>$mngrp</td><td>$mgrpstrs</td><td>$regdate</td><td>$comcount</td><td>$pagecount</td><td>$pfscount</td><td>$postcount</td>".$karma.$medals."<td>$rating</td></tr>", "user" => $user);


Автор: Oughtem 4.2.2009, 15:53
Это классно, что вы заставляете думать, но я вообще ничего не понимаю в PHP, хотя оч. хочу научиться хотя бы "читать" код. Я так понимаю, что кусок кода, где мне надо рыться это 

Код
$user_array[$rating*100][$row['user_id']] = array("str" => "<tr><td>$user</td><td>$mngrp</td><td>$mgrpstrs</td><td>$regdate</td><td>$comcount</td><td>$pagecount</td><td>$pfscount</td><td>$postcount</td>".$karma.$medals."<td>$rating</td></tr>", "user" => $user);
                }
        }

krsort($user_array);


foreach($user_array as $k)
        {
                foreach($k as $i)
                        {
                                $user_list .= $i['str'];
                                if ($topcount < $top_limit){$top[] = $i['user'];}
                                $topcount++;
                        }
        }


я хочу сам разобраться без прямой подсказки типа "замени это на это". Но я не понимаю до конца суть данного участка кода. Вот как я вижу этот код 
1. uksort сортирует массив заданный этим: $user_array[$rating*100][$row['user_id']] = array("str" => ..... Индексом выступает [$rating*100], что такое [$row['user_id']]  и array("str" =>   - я не пойму.
2. Идёт "обход" массива (это я читал) с помощью foreach. Зачем оно нужно я тоже не пойму. Но ладно, дальше.  $user_array должен восприниматься как $k, $k как $i Зачем - не понятно.
3. Суть этого участка 
Код
 {
                                $user_list .= $i['str'];
                                if ($topcount < $top_limit){$top[] = $i['user'];}
                                $topcount++;
                        }

для меня вообще покрыта мраком.
Вот так и кручу этот код  smile 

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

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)