is_utf8() – auf UTF-8 prüfen

September 2009

Mit dieser Funktion lässt sich feststellen, ob eine Zeichenkette als UTF-8 kodiert ist oder nicht, oder zumindest den Anschein macht, es zu sein.
Sie prüft den String auf ungültige UTF-8-Zeichen bzw. -Bytes und gibt false zurück, falls solche gefunden wurden.
<?php
function is_utf8($str){
  
$strlen strlen($str);
  for(
$i=0$i<$strlen$i++){
    
$ord ord($str[$i]);
    if(
$ord 0x80) continue; // 0bbbbbbb
    
elseif(($ord&0xE0)===0xC0 && $ord>0xC1$n 1// 110bbbbb (exkl C0-C1)
    
elseif(($ord&0xF0)===0xE0$n 2// 1110bbbb
    
elseif(($ord&0xF8)===0xF0 && $ord<0xF5$n 3// 11110bbb (exkl F5-FF)
    
else return false// ungültiges UTF-8-Zeichen
    
for($c=0$c<$n$c++) // $n Folgebytes? // 10bbbbbb
      
if(++$i===$strlen || (ord($str[$i])&0xC0)!==0x80)
        return 
false// ungültiges UTF-8-Zeichen
  
}
  return 
true// kein ungültiges UTF-8-Zeichen gefunden
}

# mögliche Anwendung
echo is_utf8($str) ? $str utf8_encode($str);
?>

Achtung: Diese Funktion kann ein falsches Resultat zurückgeben, wenn Zeichenfolgen aus ISO 8859 oder anderen Kodierungen zufälligerweise auch in UTF-8 gültig sind, doch dieses Phänomen dürfte nur bei willkürlichen Strings auftreten, nicht bei lesbaren Texten.
Wenn die Zeichenkette nur aus 7-Bit-Zeichen besteht, wird der String als UTF-8 angesehen auch wenn er in ISO 8859 kodiert ist, allerdings gibt es in diesem Falle keinen sichtbaren Unterschied zwischen den beiden Kodierungen.

Anmerkung: Es gibt eine RegEx-Methode, mit welcher man Strings ebenfalls auf UTF-8 überprüfen kann, doch ist die RegEx-Methode bei Zeichenketten mit über 100 Bytes deutlich langsamer.

Wenn man die Multibyte-String-Extension zur Verfügung hat, kann man einen String auch wie folgt auf seine Kodierung prüfen:
<?php
if(mb_detect_encoding($str'UTF-8, ISO-8859-1') === 'UTF-8'){
  
# der String ist in UTF-8 kodiert
}
?>

Siehe auch:

Idee von http://www.php.net/utf8-encode#39932
 


Andere Einträge


Kommentare

#1
von Clixmaster am 18.09.2010
Hatte das Problem, dass mir ein Webservice gelegentlich doppelt nach UTF-8 codierte Texte liefert, muss also nach decode nochmals geprüft werden. Fand im Web keine passende Lösung und diese hier zu kompliziert. Prüfe deshalb den String jetzt einfach auf Vorkommen von A-Tilde als Hexwert:

// doppelte Prüfung auf UTF-8 und Decodierung
if (strpos($text, 0xc3) != false) { $text = utf8_decode($text); }
if (strpos($text, 0xc3) != false) { $text = utf8_decode($text); }

Funktioniert bestens.

#2
von a.komm am 19.01.2011
Es ist nur möglich auf UTF-8 zu validieren, nicht jedoch zu prüfen ob die Information ursprünglich zur Interpretation als UTF-8 gedacht war.

function valid_utf8( $string )
{
return !((bool)preg_match('~\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF\xC0\xC1~ms',$string));
}

#3
von a.komm am 19.01.2011
Verzeihung, Regex sollte so aussehen:

'~[\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF\xC0\xC1]~ms'

#4
von Jochen Schultz am 24.02.2011
Mache mir zu Nutze, dass preg_match mit modifier u ein UTF8 codiertes Pattern benötigt. Ich übergebe als Pattern den gequoteten String und fange den Fehler ab.

Hack the Planet!


function exceptionsHandler($code,$string) { throw new Exception($string); }
function is_utf8($str) {
set_error_handler('exceptionsHandler', E_ALL);
try {
$str = preg_quote($str);
preg_match('|'.$str.'|u','abc');
restore_error_handler();
return true;
}
catch (Exception $e) {
restore_error_handler();
return false;
}
}