I think you're making it a little more complicated than it needs to be. How about this:
As you loop through your keyword found in the DB (they could be in any order, but I'll use your examples:
automobiles
fruit
dogs
dogs
cows
mp3
cows
mp3
dogs).
Say you have an associative array to keep track of how many occurences of each keyword are found. So, for each keyword you come across, increment the value in the associative array where they key name is the keyword, like this:
$keywords_count[$keyword]++;
For example, when you come across the keyword "fruit," this would happen:
$keywords_count['fruit']++;
If the key "fruit" doesn't exist in the $keywords_count array, its value will have effectively been zero, and its value after that statement will be one. So if you went through those keywords, by the end of the loop you'd have an associative array like this:
automobiles
fruit
dogs
dogs
cows
mp3
cows
mp3
dogs
'automobiles' => 1,
'fruit' => 1,
'dogs' => 3,
'cows' => 2,
'mp3' => 2
Now it's a simple matter to sort the array in reverse (highest to lowest, which is what you want) order based on the numeric values:
arsort($keywords_count, SORT_NUMERIC);
There are no duplicates, so you now have an array with the keywords listed from highest to lowest number of appearances. If you only want the top 5, there's probably some easy way to do that, but one way that occurs to me is something like this (although there must be a more graceful way 🙂.
while (count($keywords_count) > 5) {
array_pop($keywords_count);
}
Good luck. 🙂