How to make a tag cloud in PHP, MySQL and CSS

Tag CloudToday I wanted to make a tag cloud, but all my searching proved fruitless - so I decided to stop being lazy and just work it out myself!

For my example, first you'll need a database that stores the keywords / search terms.

The way mine works is every time a search is run, I check to see if the term has been searched before. If it has, I update the counter field + 1. If the term has not been searched for before, I insert it with a counter of 1.

Alternatively you may store every search individually and use the GROUP BY clause to determine how many times the search has been run.

My query looks like this:

PHP:
  1. // don't forget to connect to DB first!
  2.  
  3. $terms = array(); // create empty array
  4. $maximum = 0; // $maximum is the highest counter for a search term
  5.  
  6. $query = mysql_query("SELECT term, counter FROM search ORDER BY counter DESC LIMIT 30");
  7.  
  8. while ($row = mysql_fetch_array($query))
  9. {
  10.     $term = $row['term'];
  11.     $counter = $row['counter'];
  12.    
  13.     // update $maximum if this term is more popular than the previous terms
  14.     if ($counter> $maximum) $maximum = $counter;
  15.    
  16.     $terms[] = array('term' => $term, 'counter' => $counter);
  17.  
  18. }
  19.  
  20. // shuffle terms unless you want to retain the order of highest to lowest
  21. shuffle($terms);

Next we'll setup a bit of css. Feel free to adjust these as you see fit.

CSS:
  1. #tagcloud {
  2.     width: 300px;
  3.     background:#FFFFCC;
  4.     color:#0066FF;
  5.     padding: 10px;
  6.     border: 1px solid #FFE7B6;
  7.     text-align:center;
  8. }
  9.  
  10. #tagcloud a:link, #tagcloud a:visited {
  11.     text-decoration:none;
  12. }
  13.  
  14. #tagcloud a:hover, #tagcloud a:active {
  15.     text-decoration: underline;
  16.     color: #000;
  17. }
  18.  
  19. #tagcloud span {
  20.     padding: 4px;
  21. }
  22.  
  23. .smallest {
  24.     font-size: x-small;
  25. }
  26.  
  27. .small {
  28.     font-size: small;
  29. }
  30.  
  31. .medium {
  32.     font-size:medium;
  33. }
  34.  
  35. .large {
  36.     font-size:large;
  37. }
  38.  
  39. .largest {
  40.     font-size:larger;
  41. }

Finally we just want to loop through the array and display it with the appropriate css class.

PHP:
  1. // start the output to the page
  2. echo "<h3>Popular Searches</h3>
  3. <div id=\"tagcloud\">
  4. <div>\n";
  5.  
  6. foreach ($terms as $k) // start looping through the tags
  7. {
  8.     // determine the popularity of this term as a percentage
  9.     $percent = floor(($k['counter'] / $maximum) * 100);
  10.    
  11.     // determine the class for this term based on the percentage
  12.     if ($percent <20)
  13.     {
  14.         $class = 'smallest';
  15.     } elseif ($percent>= 20 and $percent <40) {
  16.         $class = 'small';
  17.     } elseif ($percent>= 40 and $percent <60) {
  18.         $class = 'medium';
  19.     } elseif ($percent>= 60 and $percent <80) {
  20.         $class = 'large';
  21.     } else {
  22.         $class = 'largest';
  23.     }
  24.    
  25.     // output this term
  26.     echo "<span class=\"$class\"><a href=\"search.php?search=" . urlencode($k['term']) . "\">" . $k['term'] . "</a></span>\n ";
  27. }
  28.  
  29. // close the output
  30. echo "</div>
  31. </div>\n";

And thats it! Hope this saves someone some time. Add your comments below!

Posted on 22 August '07 by Steve, under PHP.

64 Responses to “How to make a tag cloud in PHP, MySQL and CSS”

  1. Peter says:

    Just try placing tags around the css part, if that is where you are having your difficulties, then start the new blocks with the php open and close tags.

  2. Dave says:

    Hey Steve,

    Thanks for your script. I am a newbie at php and I'm currently learning it so bare with me for the simple 'stupid' question yet important to me. I am trying to implement your script and I get this error: Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING, could you direct me to what is wrong here and possibly a solution out of it?

    Much thanks!

  3. Brandon says:

    Hey Steve,

    Thanks for the script! Implementation is really nice. Took me about 4 mins to get this up and running.

    -Brandon

  4. Craig Agnew says:

    Hi Steve,

    Been looking for something exactly like this! Seen a few examples online that over-complicated things, this one does what it says on the tin. Nice job.

  5. Huurwoningen says:

    Thanks alot for the script! Works flawlessly! I could easy combine it with an other script of mine.

    Gr,

    Anthony

  6. Michael says:

    Great job, it took me some time to understand but it worked like a charm.

    Thanks

  7. Satish says:

    Thank you, Excellent piece of code..it took just few minutes to tag cloud up.

  8. Sunny says:

    Nice one Steve.
    I was having a difficult time looking for a straight forward script that could be customized for my website and this script does the job just right!

    Cheers mate.

  9. Tyler says:

    Nice example here Steve.

    I've made a few modifications to my implementation of this, and have wrapped it all into an easy to use function.

    Would it be OK if I share that function on my site? I would obviously make references to this post of yours.

  10. Steve says:

    no worries Tyler, you can reprint some/all of this code with acknowledgment.

  11. Tyler says:

    Cool Steve. I'll let you know once it's published.

  12. Tyler says:

    Steve, post is up:
    http://www.longren.org/2010/02/24/how-to-build-a-tag-cloud-with-php-mysql-and-css/

    You can delete this comment if you want, just wanted to let you know it was up and I don't have your email or any other way to contact you.

  13. Katy says:

    This is super useful, exactly what I was looking for, and I had it up and running in minutes! I changed it slightly so I could show the number of items in the categories in my database by changing the sql to "SELECT category, COUNT(category) as counter FROM table GROUP BY category", so the categories with the most items are the largest.
    Thanks!

  14. Craig says:

    Thanks a lot for this, it works great :)

Leave a Reply