Create a PHP Tag Cloud

You've probably seen a tag could or browse tags page before, but for those who haven't, it resembles a paragraph of links, with each link larger or smaller depending on the popularity of that item. It is often used for dynamic site applications, where the content changes rapidly such as news, photos, music, and video.

While browse tags pages could be guilty of being simple eye candy, they really are an effective way of displaying information. At a glance, a user can discern which are the most popular keywords or tags. Adding one of these to your site is relatively easy if you have a rudimentary knowledge of PHP. You will also need a source of data. Most likely, you will be pulling this from a database, but you could also pull it from other sources such as an xml feed or some other parsed file.

Your basic strategy:

  1. Access or retrieve information that includes a word, tag, or keyword and its popularity. Popularity should be a number that refers to how often it occurs. Popularity could be a rating from 1-10 or it could be the number of times a certain word appears in your database.
  2. Put this information into an array in PHP with the keyword as the key and the value equal to the popularity.
  3. Sort your array alphabetically by the keys.
  4. Loop through your array and display each keyword with its size dependent on the popularity value.

Step by Step PHP/MySQL Tag Cloud Explanation

1. Retrieve the Information:

This example assumes you are using MYSQL, but it can be used on all major databases with only minor changes. This example also assumes that you have already made the connection to your database earlier in the script.

The first thing we are going to do is declare our array which will eventually hold both tags and the value of their popularity. Next, we construct our SQL statement. We are going to be using a special form of SQL statements where we retrieve the count of a certain item in the database by grouping them by the field we want to count. Note that group by is different than order by and the grouping is performed before the counting is done, where the order by clause is applied last. For example if we group by the tag_name, as in this example, we are placing our results with the same tag next to each other in the results table. Now the count function is applied, and each grouping is counted. So if we have 4 results with "baseball" as the tag name, the count function returns the number 4. Notice the "as tagcount" part of the statement; this means we are assigning the count to a variable we are declaring with the name tagcount. We will reference this result number using our variable name tagcount when we retrieve our results below. We now have both the number of occurrences of a tag and the tag name itself being returned by the statement, but we also want to sort these by the number of occurrences so we have the most popular tags returned first. The order by tagcount clause does this. As you see, it is possible to order something by a variable that you declared earlier, even though it doesn't actually exist in the database. The last part of this SQL statement is also important, because we don't want to return too many results and overwhelm our visitors, so we set a limit on the number of results the database returns. I have this set to 100, which from my experience, is a good number for these purposes.

$tagArray=array();

$sql="SELECT COUNT(*) as tagcount, tag_name FROM tags 
                  GROUP BY tag_name ORDER BY tagcount DESC LIMIT 100";

if($result = mysql_query($sql))
{
     while($row = mysql_fetch_array($result))
     { 
          $tag = $row["tag_name"];
          $count = $row["tagcount"]; $tagArray[$tag]=$count;
     }
}

2. Insert data into an array:

Now that we have successfully written our SQL statement, we need to gather our results and put them into an array. You could also use PHP's object oriented capabilities and create a class for holding the results, but for this example we are trying to keep things simple.

As we loop through our results, we declare variables for our returned result fields. Using these variables, we add a new element to our tagArray array. Set the key to be the tag and the value to be the count. We know we won't overwrite the key of another entry, because the database returned unique tag names when we used the SQL group by function combined with the count function.

3. Sort array:

Now we have our values in an array, so we want to sort them alphabetically by key. We will use the PHP function ksort() for this.

ksort($tagArray);

4. Loop through the array and display each tag or keyword:

There are many ways of displaying the results of this array. Read MANY. So here is a simple non-css stab at making it work. The first thing I want to do is decide how I am going to decide what should be displayed small and decide what should be big. I want to find the maximum and minimum values in my array. To do this, I use the following snippet of code:

$min=99999999;
$max=0;

foreach($tagArray as $key=>$value)
{
     if($value>$max)
     { 
          $max=$value;
     }
     if($value<$min)
     { 
          $min=$value; 
     }
}

This will loop through my array and tell me what my minimum and maximum values are. Next I am going to use these values to make an educated guess as to the different distribution of values. I want to split the values into four segments.

$diff=$max-$min;
$highest=$max;
$middleHigh=2*ceil($diff/3)+$min;
$middleLow=1*ceil($diff/3)+$min;
$lowest=$min;

Now that I have these four variables, I can split my data into the following tiers of values

  1. x = $highest
  2. x < $highest AND x >= $middleHigh
  3. x < $middleHigh AND x >= $middleLow
  4. x < $middleLow AND x >= $lowest

Now to display each keyword all I have to do is loop through the array and test the value against each of these tiers and I will assign each tier its own text size as shown below:

foreach($tagArray as $key =>$value)
{                     
     echo "<a href='browse_tag.php?search=$key'>";

     if($value==$highest)
     {
          echo "<strong>$key</strong>";
     }
     else if(($value<$highest)&&($value>=$middleHigh))
     {
          echo "<strong>$key</strong>";
     }
     else if(($value<$middleHigh)&&($value>=$middleLow))
     {
          echo "<strong>$key</strong>";
     }
     else if(($value<$middleLow)&&($value>=$lowest))
     {
          echo "$key";
     }
     
     echo "</a> ";
}

Notice that I also have included the html link tag so that when I click on the item I will go to a page on my site that displays the results for that keyword.