How To: Build a Tag Cloud with PHP, MySQL, and CSS

Tag clouds are everywhere. They are a popular way to show the weight (read: popularity) of tags, categories, or any words really. I needed to build a tag cloud for a project at work to display categories and show how many questions were contained inside each category. Categories with more questions would need a larger font, and categories with fewer questions would need smaller fonts. I came across this post from Steve Thomas titled How to make a tag cloud in PHP, MySQL and CSS.

Steve’s code is exactly what I was looking for. I made a few modifications to his code and wrapped it all into a custom PHP function, which you can see below.

Download The Code

The function returns an array that contains each category name, the CSS class that should be applied to the given category, and the category ID for linking to the page showing only questions in that category.

<?php
function tagCloud($maximum=0) {
	$cats = array(); // create empty array
	
	$query = mysql_query("SELECT categories.catDesc, categories.catId, COUNT( questions.id ) AS totalQuestions FROM questions, categories WHERE questions.categoryId = categories.catId GROUP BY categories.catId;");
	while ($row = mysql_fetch_array($query)) {
		$cat = $row['catDesc'];
		$counter = $row['totalQuestions'];
		$catid = $row['catID'];

		// update $maximum if this term is more popular than the previous terms
		if ($counter> $maximum) $maximum = $counter;
		
		$percent = floor(($counter / $maximum) * 100);
		if ($percent <20) {
			$class = 'smallest';
		}
		elseif ($percent>= 20 and $percent <40) {
			$class = 'small';
		}
		elseif ($percent>= 40 and $percent <60) {
			$class = 'medium';
		}
		elseif ($percent>= 60 and $percent <80) {
			$class = 'large';
		}
		else {
			$class = 'largest';
		}
		$cats[] = array('term' => $cat, 'class' => $class, 'catid' => $catid);

	}
	return $cats;
}
?>

You’ll also need some CSS to style your tag cloud. This CSS is pretty much identical to what Steve published, I only made some minor changes to font sizes.

#tagcloud {
    width: 300px;
    background:#FFFFCC;
    color:#0066FF;
    padding: 10px;
    border: 1px solid #FFE7B6;
    text-align:center;
}
 
#tagcloud a:link, #tagcloud a:visited {
    text-decoration:none;
}
 
#tagcloud a:hover, #tagcloud a:active {
    text-decoration: underline;
    color: #000;
}
 
#tagcloud span {
    padding: 4px;
}
 
.smallest {
    font-size: 10px;
}
 
.small {
    font-size: 12px;
}
 
.medium {
    font-size:14px;
}
 
.large {
    font-size:16px;
}
 
.largest {
    font-size:18px;
}

To use the function, do something like this:

<?php $tagCloud = tagCloud(); foreach ($tagCloud as $t) { $cat = $t['term']; $class = $t['class']; $catid = $t['catid']; print "<span class=\"$class\"><a href=\"category.php?id=$catid\">$cat</a></span>"; } ?>

I am still testing this code, but so far it seems to do exactly what I need it to do. It’s best to use tagclouds in a virtual private server provider that supports PHP, MySQL and CSS. If you experience trouble with the code or if it doesn’t act as expected, please let me know in the comments. If you’ve got ideas on how to improve the function, I’d love to hear your thoughts as well!