nasıl php aracılığıyla bir mysql veritabanı karakter kodlamasını algılamak ve düzeltmek için?

5 Cevap php

Ben vb 3000 girdileri Çevresi E, E, O, U gibi karakterler kullanarak, demektir, Fransızca insanların isimleri ve veri dolu bu veritabanını aldık.

Görünüşe göre, veriler içinde) (utf8_encode kullanarak bazen kodlanmış, ve bazen olmuştur. Bir berbat çıktı bu sonuç: bazı yerlerde karakterler onlar değil diğerleri de, güzel göstermek.

İlk başta ben bu sorunları ortaya arabiriminde her yerde izini ve utf8_decode () gerekli kullanmayı denedim, ama gerçekten uygulanabilir bir çözüm değil.

Ben bazı test yaptım ve ilk etapta utf8_encode kullanmak için hiçbir neden yoktur, bu yüzden oldukça tüm bu kaldırmak ve sadece her yerde UTF8 çalışmak istiyorum - tarayıcı, katman ve veritabanı düzeyde. Yani ben onun kadar temizlenir sürümüne göre tüm misencoded veri dönüştürme, veritabanını temizlemek gerekir.

Soru: utf8 dize doğru (utf8_encode ile) (utf8_encode olmadan) veya kodlanmış olup olmadığını kontrol ederim php bir işlev oluşturmak ve bu olsaydı, özgün durumuna geri dönüştürmek mümkün olacaktır?

Diğer bir ifadeyle: i () d utf8_encode olmamıştır utf8 içeriğe utf8_encode () olmuştur utf8 içeriği tespit nasıl bilmek istiyorum.

** GÜNCELLEME: ÖRNEK **

Burada iyi bir örnek: Eğer özel karakter dolu bir dize almak ve) (bunu da dize ve utf8_encode bir kopyasını alır. Ben hayal ediyorum işlevi, her iki dizeleri alır bakir birinci bırakır ve ikinci dize şimdi dize biri olarak aynıdır.

Ben bu çalıştı:

$loc_fr = setlocale(LC_ALL, 'fr_BE.UTF8','fr_BE@euro', 'fr_BE', 'fr', 'fra', 'fr_FR');
$str1= "éèöûêïà ";
$str2 = utf8_encode($str1);

function convert_charset($str) {
    $charset=  mb_detect_encoding($str);
    if( $charset=="UTF-8" ) {
        return utf8_decode($str);
    }
    else {
        return $str;
    }
}
function correctString($str) {
    echo "\nbefore: $str";
    $str= convert_charset($str);
    echo "\nafter: $str"; 
}

correctString($str1);
echo('<hr/>'."\n");
correctString($str2);

Ve bu bana verir:

before: éèöûêïà after: ������� 
before: éèöûêïà  after: éèöûêïà

Teşekkürler,

Alex

5 Cevap

Bu şu anda aracılığıyla aradığınızı karakter kodlama lens soruya tamamen net değil (bu metin editörü, tarayıcı başlıklarını, veritabanı yapılandırması, vb varsayılan bağlıdır), ve hangi karakter kodlama veri geçirdi dönüşümler. Bu, örneğin, bir veritabanı yapılandırma şeyi verdiği tarafından düzeltilecektir, olabilir, ve bu verilerin parça parça değişiklik yapmak çok daha iyi.

Bu utf8 çift kodlama bir sorun olabilir gibi görünüyor, ve bu durum, orijinal ve bozuk veri utf8 olacak, böylece her iki eğer algılama kodlayan size ihtiyacınız bilgi vermeyecektir. Bu durumda yaklaşım makul veri kadar ne açabilirsiniz karakterler hakkında varsayımlar yapılmasını gerektirmektedir: kadarıyla PHP ve MySQL "Ã ©" ile ilgili olarak tamamen yasal utf8 olduğunu, bu nedenle size hakkında bildiklerini dayanan bir karar yapmak zorunda bozulmuş olması gerektiğini verileri ve yazarlar. Bunlar sadece bir teknisyen iseniz yapmak riskli varsayımlar vardır. Eğer veri Fransızca biliyor ve sadece 3000 kayıtları varsa Neyse ki, bu varsayımlar bu tür yapmak için muhtemelen ok bulunuyor.

Aşağıda bunu düzeltmek için, sonra verileri kontrol etmek, her şeyden önce uyum sağlayabilen, ve nihayet tekrar kontrol etmek için bir betik. O yapıyor bütün, utf8 olarak bir dize işlenirken karakterleri içine kırma ve beklenen Fransız karakter beyaz liste karşı karakterleri karşılaştırıyor. Dizge değil utf8 olduğu veya normal olarak, örneğin, Fransızca beklenen karakterler içeriyorsa bir sorun sinyalleri:

PROBABLY OK     Côte d'Azur
HAS NON-WHITELISTED CHAR        Côte d'Azur    195,180 ô
NON-UTF8        C�e d'Azur

İşte senaryo, sen http://hsivonen.iki.fi/php-utf8/ gelen bağımlı unicode fonksiyonlarını indirmek gerekir

<?php

// Download from http://hsivonen.iki.fi/php-utf8/
require "php-utf8/utf8.inc";

$my_french_whitelist = array_merge(
  range(0,127), // throw in all the lower ASCII chars
  array(
    0xE8, // small e-grave
    0xE9, // small e-acute
    0xF4, // small o-circumflex
    //... Will need to add other accented chars,
    // Euro sign, and whatever other chars
    // are normally expected in the data.
  )
);

// NB, whether this string literal is in utf8
// depends on the encoding of the text editor
// used to write the code
$str1 = "Côte d'Azur";
$test_data = array(
  $str1,
  utf8_encode($str1),
  utf8_decode($str1),
);

foreach($test_data as $str){
  $questionable_chars = non_whitelisted(
    $my_french_whitelist,
    $str
  );
  if($questionable_chars===true){
    p("NON-UTF8", $str);
  }else if ($questionable_chars){
    p(
      "HAS NON-WHITELISTED CHAR",
      $str,
      implode(",", $questionable_chars),
      unicodeToUtf8($questionable_chars)
    );
  }else{
    p("PROBABLY OK", $str);
  }
}

function non_whitelisted($whitelist, $utf8_str){
  $codepoints = utf8ToUnicode($utf8_str);
  if($codepoints===false){ // has non-utf8 char
    return true;
  }
  return array_diff(
    array_unique($codepoints),
    $whitelist
  );
}


function p(){
  $args = func_get_args();
  echo implode("\t", $args), "\n";
}

Ben bir daha derleme yaklaşım olabileceğini düşünüyorum. Ben dinamik DB kodlanmış bir kaç hafta geri Bulgar alınan veritabanı, ama başka bir veritabanına taşırken ben korkak var??

Ben çözüldü yolu, veritabanı damping utf8 harmanlama veritabanı ayarı ve ardından ikili olarak veri ithal oldu. Utf8 ve bu oto-dönüştürülen her şey artık bana vermedin??.

Bu MySQL oldu

Eğer veritabanına bağlanmak, her zaman mysql_set_charset ('utf8', $ db_connection) kullanmayı unutmayın;

o tüm sorunlar çözüldü, her şeyi çözecektir.

Bu bakınız: http://phpanswer.com/store-french-characters-into-mysql-db-and-display/

Eğer veri utf8_encode ISO 8859-1 dönüştürür beri veri (UTF-8 oder ISO 8859-1 ya ile kodlanmış UTF-bazen utf8_encode kullanarak dönüştürülebilir olduğunu söyledi gibi, 8). UTF-8 1100001x ile başlayan iki bayt ile 128-255 karakterleri kodlar beri, sadece veri geçerli bir UTF-8 olup olmadığını test ve eğer değilse dönüştürmek zorunda.

Yani zaten UTF-8 ise (birkaç is_utf8 fonksiyonlarına bakınız) tüm veri tarama ve UTF-8 değilse utf8_encode kullanın.

benim sorunum nedense ben é, ê düz formatında veya utf8 kodlanmış bu à gibi benim veritabanı karakter var olmasıdır. Araştırmadan sonra ben bilerek göndermek formları işleme eklenen hiçbir utf8 kodlama yoktu gibi bazı tarayıcı (IE veya FF veya başka bilmiyorum) gönderilen giriş verilerini kodlayan bir sonuç var. Yani utf8_encode ile veri okumak olsaydı, ben diğer düz karakter değiştirmek olacak, ve tersi.

My solution, after I studied solutions given above: 1. I created a new database with charset utf8 2. Imported the database AFTER I changed the charset definition on CREATE TABLE statement in sql dump file from Latin.... to UTF8. 3. import data from original database (until here maybe will be enough just to change the charset on existing db and tables, and this only if original db is not utf8) 4. update the content in database directly by replacing the utf8 encoded chars with there plain format something like

UPDATE `clients` SET `name` = REPLACE(`name`,"é",'é' )  WHERE `name` LIKE CONVERT( _latin1 '%é%' USING utf8 );
  1. Ben bir UTF8 iletişim onların olduğundan emin olmak için (php kodu için) db sınıfta bu satırı koymak

    $ This-> sorgu ('SET CHARSET UTF8');

So, ho to update? (step 4) I've built an array with possible chars that might be encoded

$special_chars = array(
  'ù','û','ü',
  'ÿ',
  'à','â','ä','å','æ',
  'ç',
  'é','è','ê','ë',
  'ï','î',
  'ô','œ','ö','ó','ø',
  'ü');

Ben güncelleştirilmesi gerektiğini tablo, alan çiftleri ile bir dizi Buit ettik

$where_to_look = array(
    array("table_name" , "field_name"),
    	..... );

, daha

    foreach($special_chars as $char)
    {
      foreach($where_to_look as $pair)
      {
        //$table = $pair[0]; $field = $pair[1]
        $sql = "SELECT id , `" . $pair[1] . "` FROM " .$pair[0] . " WHERE `" . $pair[1] . "` LIKE CONVERT( _latin1 '%" . $char . "%' USING utf8 );";

    if($db->num_rows() > 0){
         $sql1 = "UPDATE " . $pair[0] . " SET `" . $pair[1] . "` = REPLACE(`" . $pair[1] . "`,CONVERT( _latin1 '" . $char . "' USING utf8 ),'" . $char . "' )  WHERE `" . $pair[1] . "` LIKE CONVERT( _latin1 '%" . $char . "%' USING utf8 )";
         $db1->query($sql1);
        }
    }
 }

The basic ideea is to use encoding features of mysql to avoid encoding done between mysql, apache, browser and back; NOTE: I had not avaiable php functions like mb_....

En iyi