• Status: Solved
• Priority: Medium
• Security: Public
• Views: 183

# Sort by most views

Hey guys,
My problem is i have a page that displays files for download, and i need to make it so the user can select how they want to sort the downloads. One of the options is to sort them by the ones with the most hits appearing at the top and the lowest hits appearing at the bottom. I have written some code for it but it doesnt work because i am stuck with a problem, i will try and make it as clear as possible:

Example:

\$table = array("1","8",6","9");
// So element 2 of \$table is 8, and element 2 of \$hits is 3, so table 8 has 3 hits, so i can use it when getting the file from the database.
\$hits = array("7","3","4","5");

rsort(\$hits); // Sort \$hits in order from lowest to highest, in this case 3457
\$hits = array_reverse(\$hits); // Reverse \$hits so now it is from highest to lowest, in this case 7543

But now it has scrambled things, because \$hits is fine but it has been reversed, so meanwile element 2 of \$table is 8 and element 2 of \$hits is 5, witch is wrong, table 8 actully has the file of hits 3, but because things have been reversed in order to display highest to lowest it changes the correspondance between the 2 arrays elements. Understand? Please help... i need a simple as possible example or solution to this problem. Thanks
0
trent21
• 5
• 4
• 2
• +1
1 Solution

Commented:
are you loading this from a database? if so, you can add SORT BY hits DESC to the query
0

Author Commented:

1. Get all downloads from the database and display them by the most hits at the top of the page and the lowest hits at the bottom.

So basicly do you mean, i have the query to get the hits witch is \$query = "SELECT hits FROM downloads WHERE downloadid='\$i'"; and \$i is the download id witch has been iterated through with a for statement. So in order to get the hits and the downloadtext from the download id witch contains the most hits then display them by the highest hits first, i would do ?
0

Commented:

0

Author Commented:
Your code does not work, it simply orders them by there normal order.
0

Commented:
Are you really sure? If I may ask, can you post a snippet of your code for us?

It should look something like:
<?php

if(mysql_error())
{
echo '<code>An error occured while processing your searchquery</code>';
}
else
{
echo '<table>';
echo '<tr><th>Hits</th><th>Id</th><th>Text</th></tr>';
while(\$row = mysql_fetch_assoc(\$query_results))
{
echo '<tr><td>'.implode('</td><td>', \$row).'</td></tr>';
}
echo '</table>';
}

-r-
0

Commented:
array_multisort(\$hits, SORT_ASC, \$table);
// flag can also be SORT_DESC
0

Author Commented:
It definetly does not work with what you gave Roonan, it displays them all in wrong error, here is what happens when i trim it down to just hits:

Hits Id Text
7
6
2
2
10
0
0
0

You can see its obviously in wrong order...
0

Author Commented:
Here is the complete code, nevermind log.php, it has nothing to do with the problem...

<?php

include("log.php");

// Database
\$db = mysql_connect("localhost","profchemx");
\$res = mysql_query(\$que);
\$rows = mysql_num_rows(\$res);
\$rowhits = array();
\$tablenum = array();
// Database

for(\$i = 0; \$i<(\$rows + 1); \$i++)
{
// Database 2
\$result = mysql_query(\$query);
\$hits = mysql_result(\$result, 0);

\$rowhits[\$i] = \$hits;
\$tablenum[\$i] = \$i;

// Database 2
}

natsort(\$rowhits);
\$rowhits = array_reverse(\$rowhits);

// Scan through array and print all its elements.
for(\$i = 0; \$i<count(\$rowhits); \$i++)
{
\$resul = mysql_query(\$quer);
\$dcode = mysql_result(\$resul,0);

if(!\$resul)
{
print mysql_error();
}
else
{
eval("\\$dcode = \"\$dcode\";");
print \$dcode;

}
}
// Scan through array and print all its elements

?>

Now this code i wrote works, it displays downloads by there highest to lowest, but it displays them twice well allot of them, and we no as i said this is because the correspondance between the arrays tablenum and rowhits change when the array is reversed. Hope this can help...
0

Commented:
Yeah, but want I ment is that you have somewhat of an overkill on your queries, because afterall you would like to show ALL downloads available and not just a selection. Therefor you could just request them from the database in the correct ordering (order by hits in your/our case). This is done by using the code I posted earlier, but I suppose I am seeing things not that clearly this early in the morning.

What I see is happening in your code is this:
2. For each download retrieve the number of hits (which are already in the results done by the query at step 1)
3. Fill 2 paralel arrays with this data.
4. Do somekind of phpbased sorting (whereas sorting on mysql-level/step 1 should do the trick.)
5. Try to rematch the relation between the two arrays at stage 3.
6. Output things.

My suggestion would then be:
6. Output things.

possibly you could explain things in a non code matter like the stageplan I wrote, for me?

regards

-r-
0

Author Commented:
Thats correct friend, you understand it well... i know the order should be right, but maybe it is the server im testing it on? It is a Lycos server, although the code you posted earlier doesnt print them by the highest first. This is very weird, it should but it doesnt, trust me, i no your right but what other options can we do here? What other SQL query can i try?
0

Commented:
You could use usort thats is easier than the way you are using now, and hopefully will work:

usort is used to execute a custom ordering using a callback function. in this callback function we compare the hits field and return -1 when a<b, 0 when a=b, 1 when a>b.

I'm not familiar with the php-limitations there might or might not be on lycos systems, so I can't say something usefull about that issue.

<?php
/*connect first*/

//query db
if(mysql_error()) exit('DB flaw');

//fetch records
\$records = array();
while(\$record = mysql_fetch_assoc(\$q))
\$record = \$records;

//sort records
usort(\$records, 'sortbyhit');

echo '<div>We have '.count(\$records).' records.</div>';

//output data
echo '<table>';
foreach(\$records as \$record)
{
echo '<tr><td>'.implode('</td><td>', \$record).'</td></tr>';
}
echo '</table>';
//supportive methods below
function sortbyhit(\$rec1, \$rec2)
{
if(!is_array(\$rec1) || !is_array(\$rec2)) return 0;

if (\$rec1['hits'])  == \$rec2['hits']) {
return 0;
}
return (\$rec1['hits'])  < \$rec2['hits']) ) ? -1 : 1;
}

?>
0

Commented:
Or if it isnt too much trouble move to another free php/sql host (like codewarz.net, the one i use)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.