I had a strange series of discoveries while working with the CakeAssets Plugin today. One of the many ways a simple issue can turn into a strange journey of debugging.

When working on the style of a website, I noticed that the first line of CSS wasn't rendering in the page. When I inspected the combined CSS page, I saw that there were strange characters at the beginning of the first line (see the banner image).

The CSS is built in SASS, and then CakeAssets takes all of the CSS files in the website and combines them together. I checked my SASS and couldn't find any stray characters. Even stranger, the CSS file on it's own (before CakeAssets took over) didn't appear to have a random character in it.

I started commenting out lines in the SASS file, and found that the strange character didn't show up if I commented out one specific line - a line including a unicode Font-Awesome value. The plot thickens.

I traced the CakeAssets code back to how it loads the CSS info. We basically just have:

function fileGetContents($path) {
	return file_get_content($path);
}

I found a very helpful StackOverflow article talking about that method adding crazy characters if you're pulling a UTF-8 encoded file. They recommended using mb_detect_encoding and mb_convert_encoding. Great. So now we've got:

function fileGetContents($path) {
	$content = file_get_content($path);
	// Ensures content is UTF-8
	return mb_convert_encoding($content, 'UTF-8', 
		mb_detect_encoding($content, 'UTF-8, ISO-8859-1', true));
}

Ok, now that pesky sucker looks like . After Googling on that for a bit, I tried converting the number to hexadecimal, which is instead FEFF. That lead to something called the "byte-order-mark", or BOM. Apparently it's a character inserted into the beginning of every document that includes unicode. It's invisible on it's own, but not if it's being converted to UTF-8 and being copied into the middle of the document.

So now we've got:

function fileGetContents($path) {
	$content = file_get_contents($path);
	// Ensures content is UTF-8
	if (function_exists("mb_convert_encoding")) {
		$content = mb_convert_encoding($content, 'UTF-8', 
			mb_detect_encoding($content, 'UTF-8, ISO-8859-1', true));
	}
	$content = str_replace("\xEF\xBB\xBF",'',$content); // Remove Byte Order Mark
	return $content;
}

It was a long, weird morning, but the CSS looks great now!