function truncate_utf8($string, $len, $wordsafe) is essentially this:
while (ord($string[--$len]) < 0xC0) {};
This is dangerous because crafted $string may cause infinite loop.
Also, the semicolon after { } is superfluous ;-)
The last four lines of this function may be rewritten:
while ((ord($string[$len]) & 0xC0) == 0x80 && $len > 0) { $len--; }
return substr($string, 0, $len);
This should be safe and also correct.
A more elaborate version I use: