it-swarm.com.de

Codierung erkennen und alles UTF-8 machen

Ich lese viele Texte aus verschiedenen RSS-Feeds aus und füge sie in meine Datenbank ein.

Natürlich gibt es mehrere unterschiedliche Zeichenkodierungen, die in den Feeds verwendet werden, z. UTF-8 und ISO 8859-1.

Leider gibt es manchmal Probleme mit der Kodierung der Texte. Beispiel:

  1. Das "ß" in "Fußball" sollte in meiner Datenbank so aussehen: "Ÿ". Wenn es sich um ein "Ÿ" handelt, wird es korrekt angezeigt.

  2. Manchmal sieht das "ß" in "Fußball" in meiner Datenbank so aus: "ß". Dann wird es natürlich falsch angezeigt.

  3. In anderen Fällen wird das "ß" als "ß" gespeichert - also ohne Änderung. Dann wird es auch falsch angezeigt.

Was kann ich tun, um die Fälle 2 und 3 zu vermeiden?

Wie kann ich alles gleich codieren, am besten UTF-8? Wann muss ich utf8_encode() verwenden, wann muss ich utf8_decode() verwenden (es ist klar, was der Effekt ist, aber wann muss ich die Funktionen verwenden?) Und wann muss ich nichts mit der Eingabe tun?

Wie mache ich alles die gleiche Kodierung? Vielleicht mit der Funktion mb_detect_encoding()? Kann ich dafür eine Funktion schreiben? Also meine Probleme sind:

  1. Wie finde ich heraus, welche Codierung der Text verwendet?
  2. Wie kann ich es in UTF-8 konvertieren - unabhängig von der alten Codierung?

Würde eine solche Funktion funktionieren?

function correct_encoding($text) {
    $current_encoding = mb_detect_encoding($text, 'auto');
    $text = iconv($current_encoding, 'UTF-8', $text);
    return $text;
}

Ich habe es getestet, aber es funktioniert nicht. Was stimmt damit nicht?

287
caw

Wenn Sie utf8_encode() auf eine bereits UTF-8-Zeichenfolge anwenden, wird eine verstümmelte UTF-8-Ausgabe zurückgegeben.

Ich habe eine Funktion entwickelt, die all diese Probleme anspricht. Es heißt Encoding::toUTF8().

Sie müssen nicht wissen, wie die Codierung Ihrer Zeichenfolgen lautet. Es kann Latin1 ( ISO 8859-1) , Windows-1252 oder UTF-8 sein, oder die Zeichenfolge kann eine Mischung von ihnen haben. Encoding::toUTF8() konvertiert alles nach UTF-8.

Ich tat es, weil ein Dienst mir einen Datenfeed lieferte, der alle durcheinander brachte und UTF-8 und Latin1 in derselben Zeichenfolge mischte.

Verwendungszweck:

require_once('Encoding.php');
use \ForceUTF8\Encoding;  // It's namespaced now.

$utf8_string = Encoding::toUTF8($utf8_or_latin1_or_mixed_string);

$latin1_string = Encoding::toLatin1($utf8_or_latin1_or_mixed_string);

Herunterladen:

https://github.com/neitanod/forceutf8

Ich habe eine weitere Funktion, Encoding::fixUFT8(), eingefügt, die jeden verstümmelten UTF-8-String korrigiert.

Verwendungszweck:

require_once('Encoding.php');
use \ForceUTF8\Encoding;  // It's namespaced now.

$utf8_string = Encoding::fixUTF8($garbled_utf8_string);

Beispiele:

echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("FÃÂédÃÂération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");

wird ausgeben:

Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football

Ich habe die Funktion (forceUTF8) In eine Familie statischer Funktionen für eine Klasse namens Encoding umgewandelt. Die neue Funktion ist Encoding::toUTF8().

343

Sie müssen zuerst feststellen, welche Codierung verwendet wurde. Wenn Sie RSS-Feeds analysieren (wahrscheinlich über HTTP), sollten Sie die Codierung aus dem charset -Parameter von Content-Type HTTP-Header-Feld . Ist dies nicht der Fall, lesen Sie die Codierung aus dem encoding -Attribut der XML-Verarbeitungsanweisung . Wenn auch das fehlt, verwenden Sie UTF-8 wie in der Spezifikation definiert .


Bearbeiten Folgendes würde ich wahrscheinlich tun:

Ich würde cURL verwenden, um die Antwort zu senden und abzurufen. Auf diese Weise können Sie bestimmte Headerfelder festlegen und auch den Antwortheader abrufen. Nach dem Abrufen der Antwort müssen Sie die HTTP-Antwort analysieren und in Header und Body aufteilen. Der Header sollte dann das Content-Type Header-Feld, das den MIME-Typ und (hoffentlich) den charset -Parameter mit der Kodierung/dem Zeichensatz enthält. Wenn nicht, analysieren wir den XML-PI auf das Vorhandensein des encoding -Attributs und rufen die Codierung von dort ab. Wenn dies ebenfalls fehlt, wird in den XML-Spezifikationen die Verwendung von UTF-8 als Codierung definiert.

$url = 'http://www.lr-online.de/storage/rss/rss/sport.xml';

$accept = array(
    'type' => array('application/rss+xml', 'application/xml', 'application/rdf+xml', 'text/xml'),
    'charset' => array_diff(mb_list_encodings(), array('pass', 'auto', 'wchar', 'byte2be', 'byte2le', 'byte4be', 'byte4le', 'BASE64', 'UUENCODE', 'HTML-ENTITIES', 'Quoted-Printable', '7bit', '8bit'))
);
$header = array(
    'Accept: '.implode(', ', $accept['type']),
    'Accept-Charset: '.implode(', ', $accept['charset']),
);
$encoding = null;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
$response = curl_exec($curl);
if (!$response) {
    // error fetching the response
} else {
    $offset = strpos($response, "\r\n\r\n");
    $header = substr($response, 0, $offset);
    if (!$header || !preg_match('/^Content-Type:\s+([^;]+)(?:;\s*charset=(.*))?/im', $header, $match)) {
        // error parsing the response
    } else {
        if (!in_array(strtolower($match[1]), array_map('strtolower', $accept['type']))) {
            // type not accepted
        }
        $encoding = trim($match[2], '"\'');
    }
    if (!$encoding) {
        $body = substr($response, $offset + 4);
        if (preg_match('/^<\?xml\s+version=(?:"[^"]*"|\'[^\']*\')\s+encoding=("[^"]*"|\'[^\']*\')/s', $body, $match)) {
            $encoding = trim($match[1], '"\'');
        }
    }
    if (!$encoding) {
        $encoding = 'utf-8';
    } else {
        if (!in_array($encoding, array_map('strtolower', $accept['charset']))) {
            // encoding not accepted
        }
        if ($encoding != 'utf-8') {
            $body = mb_convert_encoding($body, 'utf-8', $encoding);
        }
    }
    $simpleXML = simplexml_load_string($body, null, LIBXML_NOERROR);
    if (!$simpleXML) {
        // parse error
    } else {
        echo $simpleXML->asXML();
    }
}
72
Gumbo

Das Erkennen der Codierung ist schwierig.

mb_detect_encoding basiert auf einer Reihe von Kandidaten, die Sie für erfolgreich befunden haben. In einigen Codierungen sind bestimmte Byte-Sequenzen ungültig und können daher zwischen verschiedenen Kandidaten unterscheiden. Leider gibt es viele Kodierungen, bei denen die gleichen Bytes gültig sind (aber unterschiedlich). In diesen Fällen kann die Codierung nicht ermittelt werden. Sie können Ihre eigene Logik implementieren, um in diesen Fällen Vermutungen anzustellen. Beispielsweise ist es wahrscheinlicher, dass Daten, die von einer japanischen Site stammen, eine japanische Codierung aufweisen.

Solange Sie sich nur mit westeuropäischen Sprachen befassen, sind die drei wichtigsten Kodierungen utf-8, iso-8859-1 und cp-1252. Da dies für viele Plattformen Standardwerte sind, werden sie auch am häufigsten falsch gemeldet. Z.B. Wenn Leute unterschiedliche Kodierungen verwenden, sind sie wahrscheinlich ehrlich, da sonst ihre Software sehr oft kaputt geht. Daher ist es eine gute Strategie, dem Anbieter zu vertrauen, es sei denn, die Codierung wird als eine dieser drei angegeben. Sie sollten immer noch überprüfen, ob es tatsächlich gültig ist, indem Sie mb_check_encoding (Beachten Sie, dass gültig nicht dasselbe ist wie Sein - dieselbe Eingabe kann für viele Codierungen gültig sein). Wenn es einer von denen ist, können Sie mb_detect_encoding, um zwischen ihnen zu unterscheiden. Zum Glück ist das ziemlich deterministisch; Sie müssen nur die richtige Erkennungssequenz verwenden, nämlich UTF-8,ISO-8859-1,WINDOWS-1252.

Sobald Sie die Codierung erkannt haben, müssen Sie sie in Ihre interne Darstellung konvertieren (UTF-8 ist die einzig vernünftige Wahl. Die Funktion utf8_encode transformiert ISO-8859-1 bis UTF-8, kann also nur für diesen bestimmten Eingabetyp verwendet werden. Verwenden Sie für andere Codierungen mb_convert_encoding.

36
troelskn

Ein wirklich guter Weg, um ein isUTF8- Funktion finden Sie unter php.net :

function isUTF8($string) {
    return (utf8_encode(utf8_decode($string)) == $string);
}
14
harpax

Dieses Cheatsheet listet einige allgemeine Vorbehalte in Bezug auf die UTF-8-Behandlung in PHP auf: http://developer.loftdigital.com/blog/php-utf-8-cheatsheet

Diese Funktion zum Erkennen von Multibyte-Zeichen in einer Zeichenfolge kann sich auch als hilfreich erweisen ( source ):


function detectUTF8($string)
{
    return preg_match('%(?:
        [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
        |\xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
        |[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
        |\xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
        |\xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
        |[\xF1-\xF3][\x80-\xBF]{3}         # planes 4-15
        |\xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
        )+%xs', 
    $string);
}
12
miek

Ein bisschen Kopf hoch. Sie sagten, dass "ß" in Ihrer Datenbank als "Ÿ" angezeigt werden soll.

Dies liegt wahrscheinlich daran, dass Sie eine Datenbank mit Latin-1-Zeichencodierung verwenden oder möglicherweise Ihre PHP-MySQL-Verbindung falsch eingestellt ist. Dies bedeutet, dass P glaubt, dass MySQL auf die Verwendung von UTF-8 eingestellt ist, sodass Daten als UTF-8 gesendet werden , aber MySQL glaubt, dass PHP als ISO 8859-1 codierte Daten gesendet werden, daher wird möglicherweise erneut versucht, Ihre gesendeten Daten als UTF-8 zu codieren, was zu solchen Problemen führen kann.

Schauen Sie sich mysql_set_charset an. Es kann dir helfen.

9
Krynble

Sie müssen den Zeichensatz bei der Eingabe testen, da die Antworten mit unterschiedlichen Kodierungen codiert werden können.

Ich erzwinge, dass alle Inhalte in UTF-8 gesendet werden, indem Erkennung und Übersetzung mit der folgenden Funktion durchgeführt werden:

function fixRequestCharset()
{
  $ref = array(&$_GET, &$_POST, &$_REQUEST);
  foreach ($ref as &$var)
  {
    foreach ($var as $key => $val)
    {
      $encoding = mb_detect_encoding($var[$key], mb_detect_order(), true);
      if (!$encoding)
        continue;
      if (strcasecmp($encoding, 'UTF-8') != 0)
      {
        $encoding = iconv($encoding, 'UTF-8', $var[$key]);
        if ($encoding === false)
          continue;
        $var[$key] = $encoding;
      }
    }
  }
}

Diese Routine wandelt alle PHP Variablen, die vom entfernten Host kommen, in UTF-8 um.

Oder ignorieren Sie den Wert, wenn die Codierung nicht erkannt oder konvertiert werden konnte.

Sie können es an Ihre Bedürfnisse anpassen.

Rufen Sie es einfach auf, bevor Sie die Variablen verwenden.

3
cavila

Das Interessante an mb_detect_encoding und mb_convert_encoding ist, dass die Reihenfolge der von Ihnen vorgeschlagenen Kodierungen von Bedeutung ist:

// $input is actually UTF-8

mb_detect_encoding($input, "UTF-8", "ISO-8859-9, UTF-8");
// ISO-8859-9 (WRONG!)

mb_detect_encoding($input, "UTF-8", "UTF-8, ISO-8859-9");
// UTF-8 (OK)

Daher möchten Sie möglicherweise eine bestimmte Reihenfolge verwenden, wenn Sie erwartete Codierungen angeben. Beachten Sie jedoch, dass dies nicht narrensicher ist.

3
Halil Özgür

Ihre Kodierung sieht so aus, als ob Sie zweimal in UTF-8 kodiert haben ; das heißt, von einer anderen Codierung in UTF-8 und erneut in UTF-8. Als hätten Sie ISO 8859-1, konvertiert von ISO 8859-1 nach UTF-8 und behandelt die neue Zeichenfolge als ISO 8859-1 für eine weitere Konvertierung in UTF-8.

Hier ist ein Pseudocode von dem, was du getan hast:

$inputstring = getFromUser();
$utf8string = iconv($current_encoding, 'utf-8', $inputstring);
$flawedstring = iconv($current_encoding, 'utf-8', $utf8string);

Du solltest es versuchen:

  1. erkennen Sie die Codierung mit mb_detect_encoding() oder was auch immer Sie verwenden möchten
  2. wenn es sich um UTF-8 handelt, konvertieren Sie in ISO 8859-1 und wiederholen Sie Schritt 1
  3. schließlich konvertieren Sie zurück in UTF-8

Das setzt voraus, dass Sie bei der "mittleren" Konvertierung ISO 8859-1 verwendet haben. Wenn Sie Windows-1252 verwendet haben, konvertieren Sie in Windows-1252 (latin1). Die ursprüngliche Quellcodierung ist nicht wichtig. Die, die Sie in der fehlerhaften zweiten Konvertierung verwendet haben, ist.

Dies ist meine Vermutung, was passiert ist; Sie hätten sonst kaum etwas tun können, um vier Bytes anstelle eines erweiterten ASCII byte) zu erhalten.

Die deutsche Sprache verwendet auch ISO 8859-2 und Windows-125 (Latin-2).

3
Ivan Vučica

Die Zeichenkodierung von RSS-Feeds zu erarbeiten, scheint kompliziert zu sein. Sogar normale Webseiten lassen oft ihre Kodierung aus oder lügen darüber.

Sie könnten also versuchen, die Kodierung auf die richtige Weise zu erkennen und dann auf eine Art automatische Erkennung (Vermutung) zurückzugreifen.

2
Kevin ORourke

Ich weiß, dass dies eine ältere Frage ist, aber ich finde, dass eine nützliche Antwort niemals weh tut. Ich hatte Probleme mit der Codierung zwischen einer Desktopanwendung, SQLite und GET/POST-Variablen. Einige wären in UTF-8, andere in ASCII, und im Grunde würde alles schief gehen, wenn fremde Zeichen involviert würden.

Hier ist meine Lösung. Es löscht Ihr GET/POST/REQUEST (ich habe Cookies ausgelassen, aber Sie können sie bei Bedarf hinzufügen) bei jedem Laden der Seite vor der Verarbeitung. Es funktioniert gut in einem Header. PHP gibt Warnungen aus, wenn die Quellcodierung nicht automatisch erkannt wird. Diese Warnungen werden mit @ unterdrückt.

//Convert everything in our vars to UTF-8 for playing Nice with the database...
//Use some auto detection here to help us not double-encode...
//Suppress possible warnings with @'s for when encoding cannot be detected
try
{
    $process = array(&$_GET, &$_POST, &$_REQUEST);
    while (list($key, $val) = each($process)) {
        foreach ($val as $k => $v) {
            unset($process[$key][$k]);
            if (is_array($v)) {
                $process[$key][@mb_convert_encoding($k,'UTF-8','auto')] = $v;
                $process[] = &$process[$key][@mb_convert_encoding($k,'UTF-8','auto')];
            } else {
                $process[$key][@mb_convert_encoding($k,'UTF-8','auto')] = @mb_convert_encoding($v,'UTF-8','auto');
            }
        }
    }
    unset($process);
}
catch(Exception $ex){}
2
jocull

Ich habe seit Jahren nach Lösungen für die Kodierung gesucht , und diese Seite ist wahrscheinlich das Ergebnis jahrelanger Suche! Ich habe einige der von Ihnen genannten Vorschläge getestet und hier meine Notizen:

Das ist mein Teststring:

dies ist eine "Wröng Wröng" -Saite, die ich unbedingt sehen muss, um sie zu sehen. & das ist es!

Ich füge einen INSERT-Befehl ein, um diesen String in einer Datenbank in einem Feld zu speichern, das auf utf8_general_ci Gesetzt ist.

Der Zeichensatz meiner Seite ist UTF-8.

Wenn ich einfach so ein INSERT mache, habe ich in meiner Datenbank einige Zeichen, die wahrscheinlich vom Mars kommen ...

Also muss ich sie in ein "vernünftiges" UTF-8 konvertieren. Ich habe utf8_encode() ausprobiert, aber immer noch dringen Aliens-Zeichen in meine Datenbank ein ...

Also habe ich versucht, die Funktion forceUTF8 Zu verwenden, die auf Nummer 8 gepostet wurde, aber in der Datenbank sieht die gespeicherte Zeichenfolge folgendermaßen aus:

dies ist eine "wringend geschriebene" Saite, die ich unbedingt haben muss, um sie zu sehen, konvertiert von function !! & das ist es!

Sammeln Sie also mehr Informationen auf dieser Seite und fügen Sie sie mit anderen Informationen auf anderen Seiten zusammen. Ich habe mein Problem mit dieser Lösung gelöst:

$finallyIDidIt = mb_convert_encoding(
  $string,
  mysql_client_encoding($resourceID),
  mb_detect_encoding($string)
);

Jetzt habe ich in meiner Datenbank meine Zeichenfolge mit der richtigen Codierung.

HINWEIS: Nur zu beachtender Hinweis ist in Funktion mysql_client_encoding! Sie müssen mit der Datenbank verbunden sein, da diese Funktion eine Ressourcen-ID als Parameter benötigt.

Aber gut, ich mache diese Neucodierung einfach vor meinem INSERT, so dass es für mich kein Problem ist.

2
Mauro

Es ist ganz einfach: Wenn Sie etwas erhalten, das nicht UTF-8 ist, müssen Sie encode dass into UTF-8.

Wenn Sie also einen bestimmten Feed abrufen, der ISO 8859-1 entspricht, analysieren Sie ihn durch utf8_encode.

Wenn Sie jedoch einen UTF-8-Feed abrufen, müssen Sie nichts unternehmen.

2
Seb

php.net/ mb_detect_encoding

echo mb_detect_encoding($str, "auto");

oder

echo mb_detect_encoding($str, "UTF-8, ASCII, ISO-8859-1");

ich weiß wirklich nicht, was die Ergebnisse sind, aber ich würde vorschlagen, dass Sie nur einige Ihrer Feeds mit verschiedenen Codierungen nehmen und versuchen, wenn mb_detect_encoding funktioniert oder nicht.

update
auto steht für "ASCII, JIS, UTF-8, EUC-JP, SJIS". Es gibt den erkannten Zeichensatz zurück, mit dem Sie den String mit iconv in utf-8 konvertieren können.

<?php
function convertToUTF8($str) {
    $enc = mb_detect_encoding($str);

    if ($enc && $enc != 'UTF-8') {
        return iconv($enc, 'UTF-8', $str);
    } else {
        return $str;
    }
}
?>

ich habe es nicht getestet, daher keine Garantie. und vielleicht gibt es einen einfacheren Weg.

1
stefs

@harpax das hat bei mir funktioniert. In meinem Fall ist das gut genug:

if (isUTF8($str)) { 
    echo $str; 
}
else
{
    echo iconv("ISO-8859-1", "UTF-8//TRANSLIT", $str);
}
1
PJ Brunet

Ÿ ist Mojibake für ß. In Ihrer Datenbank haben Sie möglicherweise hex

DF if the column is "latin1",
C39F if the column is utf8 -- OR -- it is latin1, but "double-encoded"
C383C5B8 if double-encoded into a utf8 column

Sie sollten keine Kodierungs-/Dekodierungsfunktionen in PHP verwenden ; Stattdessen sollten Sie die Datenbank und die Verbindung dazu korrekt einrichten.

Wenn MySQL beteiligt ist, lesen Sie: Probleme mit utf8-Zeichen; was ich sehe, ist nicht das, was ich gespeichert habe

0
Rick James

Vergessen Sie nach dem Aussortieren Ihrer PHP-Skripte nicht, mysql mitzuteilen, welchen Zeichensatz Sie übergeben und welche Sie empfangen möchten.

Beispiel: Zeichensatz utf8

Das Übergeben von utf8-Daten an eine latin1-Tabelle in einer latin1-E/A-Sitzung gibt diesen bösen Birdfeets. Das sehe ich jeden zweiten Tag in oscommerce-Läden. Zurück und viertens mag es richtig erscheinen. Aber phpmyadmin wird die Wahrheit zeigen. Wenn Sie mysql mitteilen, welchen Zeichensatz Sie übergeben, wird die Konvertierung von mysql-Daten für Sie erledigt.

Wie man vorhandene verschlüsselte MySQL-Daten wiederherstellt, ist ein weiterer Diskussionspunkt. :)

0
tim

Holen Sie sich die Kodierung aus den Headern und konvertieren Sie sie in utf-8.

$post_url='http://website.domain';

/// Get headers ////////////////////////////////////////////////////////////
function get_headers_curl($url) 
{ 
    $ch = curl_init(); 

    curl_setopt($ch, CURLOPT_URL,            $url); 
    curl_setopt($ch, CURLOPT_HEADER,         true); 
    curl_setopt($ch, CURLOPT_NOBODY,         true); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($ch, CURLOPT_TIMEOUT,        15); 

    $r = curl_exec($ch); 
    return $r; 
}
$the_header = get_headers_curl($post_url);
/// check for redirect /////////////////////////////////////////////////
if (preg_match("/Location:/i", $the_header)) {
    $arr = explode('Location:', $the_header);
    $location = $arr[1];

    $location=explode(chr(10), $location);
    $location = $location[0];

$the_header = get_headers_curl(trim($location));
}
/// Get charset /////////////////////////////////////////////////////////////////////
if (preg_match("/charset=/i", $the_header)) {
    $arr = explode('charset=', $the_header);
    $charset = $arr[1];

    $charset=explode(chr(10), $charset);
    $charset = $charset[0];
    }
///////////////////////////////////////////////////////////////////////////////
// echo $charset;

if($charset && $charset!='UTF-8') { $html = iconv($charset, "UTF-8", $html); }
0
Arsen

Die am häufigsten gewählte Antwort funktioniert nicht. Hier ist meine und hoffe, es hilft.

function toUTF8($raw) {
    try{
        return mb_convert_encoding($raw, "UTF-8", "auto"); 
    }catch(\Exception $e){
        return mb_convert_encoding($raw, "UTF-8", "GBK"); 
    }
}
0
fzyzcjy

Diese Version ist für die deutsche Sprache, aber Sie können die $ CHARSETS und die $ TEACHERS ändern

class CharsetDetector
{
private static $CHARSETS = array(
"ISO_8859-1",
"ISO_8859-15",
"CP850"
);
private static $TESTCHARS = array(
"€",
"ä",
"Ä",
"ö",
"Ö",
"ü",
"Ü",
"ß"
);
public static function convert($string)
{
    return self::__iconv($string, self::getCharset($string));
}
public static function getCharset($string)
{
    $normalized = self::__normalize($string);
    if(!strlen($normalized))return "UTF-8";
    $best = "UTF-8";
    $charcountbest = 0;
    foreach (self::$CHARSETS as $charset) {
        $str = self::__iconv($normalized, $charset);
        $charcount = 0;
        $stop   = mb_strlen( $str, "UTF-8");

        for( $idx = 0; $idx < $stop; $idx++)
        {
            $char = mb_substr( $str, $idx, 1, "UTF-8");
            foreach (self::$TESTCHARS as $testchar) {

                if($char == $testchar)
                {

                    $charcount++;
                    break;
                }
            }
        }
        if($charcount>$charcountbest)
        {
            $charcountbest=$charcount;
            $best=$charset;
        }
        //echo $text."<br />";
    }
    return $best;
}
private static function __normalize($str)
{

$len = strlen($str);
$ret = "";
for($i = 0; $i < $len; $i++){
    $c = ord($str[$i]);
    if ($c > 128) {
        if (($c > 247)) $ret .=$str[$i];
        elseif ($c > 239) $bytes = 4;
        elseif ($c > 223) $bytes = 3;
        elseif ($c > 191) $bytes = 2;
        else $ret .=$str[$i];
        if (($i + $bytes) > $len) $ret .=$str[$i];
        $ret2=$str[$i];
        while ($bytes > 1) {
            $i++;
            $b = ord($str[$i]);
            if ($b < 128 || $b > 191) {$ret .=$ret2; $ret2=""; $i+=$bytes-1;$bytes=1; break;}
            else $ret2.=$str[$i];
            $bytes--;
        }
    }
}
return $ret; 
}
private static function __iconv($string, $charset)
{
    return iconv ( $charset, "UTF-8" , $string );
}
}
0

Ich finde hier eine Lösung http://deer.org.ua/2009/10/06/1/

class Encoding
{
    /**
     * http://deer.org.ua/2009/10/06/1/
     * @param $string
     * @return null
     */
    public static function detect_encoding($string)
    {
        static $list = ['utf-8', 'windows-1251'];

        foreach ($list as $item) {
            try {
                $sample = iconv($item, $item, $string);
            } catch (\Exception $e) {
                continue;
            }
            if (md5($sample) == md5($string)) {
                return $item;
            }
        }
        return null;
    }
}

$content = file_get_contents($file['tmp_name']);
$encoding = Encoding::detect_encoding($content);
if ($encoding != 'utf-8') {
    $result = iconv($encoding, 'utf-8', $content);
} else {
    $result = $content;
}

Ich denke, dass @ eine schlechte Entscheidung ist, und nehme einige Änderungen an der Lösung von deer.org.ua vor;

0
Paul