Christian Kruse: UTF-8 in ISO-8859-1 plus numerische Zeichenreferenzen wandeln

Beitrag lesen

你好 Robert,

Gibt es in PHP irgendeine Methode, die mir alle UTF-8-Zeichen, die nicht
in ISO-8859-1 enthalten sind (oder von mir aus auch alle, die nicht in
US-ASCII enthalten sind) in numerische Zeichenreferenzen (  usw.)
umwandelt?

AFAIK gibts sowas nicht eingebaut, aber es geht recht einfach:

  
function utf8_to_usascii_with_entities($str) {  
  $length = strlen($str);  
  $result = '';  
  
  for($i=0;$i<$length;) {  
    $c = ord($str{$i});  
  
    if($c < 0x80) {  
      $result .= $str{$i};  
      $i += 1;  
    }  
    elseif($c < 0xc2) return NULL;  
    elseif($c < 0xe0) {  
      if($length - $i < 2) return NULL;  
      if(!((ord($str{$i+1}) ^ 0x80) < 0x40)) return NULL;  
      $num = (($c & 0x1f) << 6) | (ord($str{$i+1}) ^ 0x80);  
      $result .= '&#'.$num.';';  
      $i += 2;  
    }  
    elseif($c < 0xf0) {  
      if($length - $i < 3) return NULL;  
      if(!((ord($str{$i+1}) ^ 0x80) < 0x40 && (ord($str{$i+2}) ^ 0x80) < 0x40 && ($c >= 0xe1 || ord($str{$i+1}) >= 0xa0))) return NULL;  
  
      $num = (($c & 0x0f) << 12) | ((ord($str{$i+1}) ^ 0x80) << 6) | (ord($str{$i+2}) ^ 0x80);  
      $result .= '&#'.$num.';';  
      $i += 3;  
    }  
    elseif($c < 0xf8) {  
      if($length - $i < 4) return NULL;  
      if(!((ord($str{$i+1}) ^ 0x80) < 0x40 && (ord($str{$i+2}) ^ 0x80) < 0x40 && (ord($str{$i+3}) ^ 0x80) < 0x40 && ($c >= 0xf1 || ord($str{$i+1} >= 0x90)))) return NULL;  
  
      $num = (($c & 0x07) << 18) | ((ord($str{$i+1}) ^ 0x80) << 12) | ((ord($str{$i+2}) ^ 0x80) << 6) | ($str{$i+3} ^ 0x80);  
      $result .= '&#'.$num.';';  
      $i += 4;  
    }  
    elseif($c < 0xfc) {  
      if($length - $i < 5) return NULL;  
      if(!((ord($str{$i+1}) ^ 0x80) < 0x40 && (ord($str{$i+2}) ^ 0x80) < 0x40 && (ord($str{$i+3}) ^ 0x80) < 0x40 && (ord($str{$i+4}) ^ 0x80) < 0x40 && ($c >= 0xf9 || ord($str{$i+1}) >= 0x88))) return NULL;  
  
      $num = (($c & 0x03) << 24) | ((ord($str{$i+1}) ^ 0x80) << 18) | ((ord($str{$i+2}) ^ 0x80) << 12) | ((ord($str{$i+3}) ^ 0x80) << 6) | (ord($str{$i+4}) ^ 0x80);  
      $result .= '&#'.$num.';';  
      $i += 5;  
    }  
    elseif($c < 0xfe) {  
      if($length - $i < 6) return NULL;  
      if(!((ord($str{$i+1}) ^ 0x80) < 0x40 && (ord($str{$i+2}) ^ 0x80) < 0x40 && (ord($str{$i+3}) ^ 0x80) < 0x40 && (ord($str{$i+4}) ^ 0x80) < 0x40 && (ord($str{$i+5}) ^ 0x80) < 0x40 && ($c >= 0xfd || $str{$i+1} >= 0x84))) return NULL;  
  
      $num = (($c & 0x01) << 30) | ((ord($str{$i+1}) ^ 0x80) << 24) | ((ord($str{$i+2}) ^ 0x80) << 18) | ((ord($str{$i+3}) ^ 0x80) << 12) | ((ord($str{$i+4}) ^ 0x80) << 6) | (ord($str{$i+5}) ^ 0x80);  
      $result .= '&#'.$num.';';  
      $i += 6;  
    }  
    else return NULL;  
  }  
  
  return $result;  
}  

Die Funktion wandelt alles, was nicht us-ascii ist, um in &#<nr>; -- die
ISO-8859-1-Unterstuetzung musst du selber bauen.

再见,
克里斯蒂安

--
Ihr wisst nicht, wie man den Menschen dient. Wie sollt ihr wissen, wie man den Goettern dienen soll?