Ben Kırık UTF8 kodlamasını tespit yardıma ihtiyacım var

9 Cevap php

Bazı kötü UTF8 kodlamasını tespit sürecinde duyuyorum. Şu anda PHP 5 ve MySQL kullanıyorum

Benim veritabanında ben yazdırma gibi kötü kodlamaları birkaç örneği var: à®

  • Veritabanı harmanlama utf8_general_ci olduğunu
  • PHP uygun UTF8 başlığını kullanıyor
  • Notepad + + BOM olmadan UTF8'i kullanmak için ayarlanır
  • veritabanı yönetim phpMyAdmin içinde ele
  • aksanlı karakterlerin tüm durumlarda kırık değil

Ne yapmam gerekiyor bana bunların doğru aksanlı UTF8 karakter à®, ÃÂ, à ¼ ve bunun gibi başkalarının örneklerini haritasına yardımcı olacak fonksiyonu çeşit.

9 Cevap

Ben 'düzeltmek' için geçmişte UTF8 kırık durumlarda bir dizi denemek zorunda kalmıştım, ve ne yazık ki çoğu zaman oldukça imkansız asla kolay değil, ve.

Eğer kırılmış tam olarak nasıl tespit edebilir ve bu her zaman aynı şekilde kırıldı sürece, o 'geri alma' hasar zor olacak.

Eğer hasar geri almak için denemek istiyorsanız, en iyi bahis 'dan' bir arada bulmak ve 'için' olduğunu görmek için size (mb_convert_encoding çağrı üzerine çeşitli girişimi bazı örnek kod) yazmaya başlamak olacaktır Verilerinizi giderir. Sonunda, hatta, çünkü söz ağrı düzeylerinin eski verileri tespit endişesi rahatsız değil genellikle iyi, ama bunun yerine sadece ileriye şeyleri düzeltmek için.

Ancak, bunu yapmadan önce, size ilk etapta bu soruna neden her şeyi düzeltmek emin olmak gerekir. Zaten DB tablo harmanlama ve editörler düzgün ayarlanmış olduğundan söz ettik. Ama her şey düzgün UTF-8 olduğundan emin olmak için kontrol etmek gerekiyor daha fazla yer vardır:

  • Make sure that you are serving your HTML as UTF-8:
    • header ("Content-Type: text / html; charset = utf-8");
  • Change your PHP default charset to utf-8:
    • ini_set ("default_charset", 'utf-8');
  • If your database doesn't ALWAYS talk in utf-8, then you may need to tell it on a per connection basis to ensure it's in utf-8 mode, in MySQL you do that by issuing:
    • charset utf8
  • You may need to tell your webserver to always try to talk in UTF8, in Apache this command is:
    • AddDefaultCharset UTF-8
  • Son olarak, DAİMA düzgün UTF-8 şikayet PHP işlevlerini kullandığınızdan emin olmak gerekir. Bu her zaman mb_* tarz 'Çokbaytlı farkında' dize işlevlerini kullanarak anlamına gelir. ) Gibi htmlspecialchars'dan (gibi işlevlerini çağırırken o da yanlış onları kodlamak değil emin olmak için sonunda uygun 'utf-8' charset parametresini içeren anlamına gelmektedir.

Eğer tüm süreç boyunca herhangi bir aşamada kadar özledim, kodlama karıştırılmış olabilir ve sorunlar ortaya çıkar. Eğer olsa UTF-8 yapmanın 'oluk' de olsun, bu tüm ikinci doğa haline gelir. Ve tabii ki, PHP6 (umarım) bu daha kolay bir sürü yapacak, getgo tam unicode şikayet olması gerekiyordu

Bu eski bir soru olduğunun farkındayım, ama ben benzer bir sorunu çözmek için çalışıyordu Google aramalarında geliyor - tuttu ve ben burada yayınlanan değildi için çalışma sona erdi gerçek çözüm. Yani ben burada bu konuya bağlı diğer bazı talihsiz geliştirici tökezlemeleri durumda bir cevap sonrası düşündüm ve onlar için çalışıyor ...

Her neyse, benim sorunum ben bir göç sırasında gizlice çift kodlanmış UTF8 karakterleri vardı ve çok geç olana kadar keşfedilmiş değil. Bana (bir başka deyişle ben orijinal veriyi yeniden ihracat seçeneği yoktu) mysql DB doğrudan kırık kodlamayı düzeltmek için izin verilen bir çözüm bulmak gerekiyordu.

Benim sorun çoğunlukla akıllı tırnaklar, tire ve bu tür bir şey oldu. Böyle € ™ yerine bir kesme işareti ya da â € œ yerine tırnak işareti â gibi karakterler vardı.

Çözüm - Allah onun bloguna yayınlanmıştır geliştirici korusun - Ben başka bir yerde yayınlanan gördüğüm herhangi çok daha kolay oldu. İşte:

mysqldump -h DB_HOST -u DB_USER -p DB_PASSWORD --opt --quote-names \
    --skip-set-charset --default-character-set=latin1 DB_NAME > DB_NAME-dump.sql

mysql -h DB_HOST -u DB_USER -p DB_PASSWORD \
    --default-character-set=utf8 DB_NAME < DB_NAME-dump.sql

İşte bu. Bu bana% 100 sorunu çözüldü içeri dışarı veri dökümü, sonra geri almak.

Source: http://blog.hno3.org/2010/04/22/fixing-double-encoded-utf-8-data-in-mysql/

Eğer zaten UTF8 dize utf8_encode () uygularsanız o bozuk bir UTF8 çıktı dönecektir.

Tüm bu sorunları gideren bir işlev yaptı. Bu Kodlama :: toUTF8 () denir.

Sen dizeleri kodlama ne olduğunu bilmek gerekmez. Bu Latin1 (iso 8859-1), Windows 1252 veya UTF8 veya dize bunların bir karışımı olabilir olabilir. Kodlama :: toUTF8 () UTF8 için her şeyi dönüştürmek olacaktır.

Bir hizmet, aynı dizede bu kodlamaları karıştırma, bana bütün berbat bir veri beslemesi veriyordu çünkü ben yaptım.

Kullanımı:

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

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

Ben başka bir işlevi, kodlama :: fixUTF8 () dahil ettik, wich UTF8 birden çok kez içine kodlanmış olmanın bozuk ürünü görünüyor her UTF8 dizesi çözecektir.

Kullanımı:

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

Örnekler:

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");

çıktısı:

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

İndir:

https://github.com/neitanod/forceutf8

Dan belirttiği gibi: ikili ve daha sonra kodlama düzeltmek / dönüştürmek için onları dönüştürmek gerekir.

Örneğin, aşağıdaki SQL latin1 olarak depolanan utf8 için çözecektir:

UPDATE table
   SET field = CONVERT( CAST(field AS BINARY) USING utf8)
 WHERE $broken_field_condition

Yolu ikili ve daha sonra kodlama düzeltmek için dönüştürmek için

Ben bu çok şık değil biliyorum, ama bu dizeleri çifte kodlanmış olabileceği belirtilmiştir sonra, ben bu fonksiyonu yaptı:

function fix_double encoding($string)
{
	$utf8_chars = explode(' ', 'À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö');
	$utf8_double_encoded = array();
	foreach($utf8_chars as $utf8_char)
	{
    		$utf8_double_encoded[] = utf8_encode(utf8_encode($utf8_char));
	}
	$string = str_replace($utf8_double_encoded, $utf8_chars, $string);
	return $string;
}

Bu ben yaşıyorum çift kodlamayı kaldırmak için mükemmel bir iş gibi görünüyor. Ben muhtemelen diğerleri için bir sorun olabilir bazı karakterler eksik. Ancak, benim ihtiyaçları için mükemmel çalışıyor.

Lütfen utf-8 noktada iso8859-1 ya da Win-1250 olarak yorumlanır ediliyor gibi görünüyor.

Dediğiniz zaman "benim veritabanında ben kötü kodlamaları birkaç örneği var" - bunu nasıl kontrol ettin mi? App, phpmyadmin veya komut satırı istemcisi üzerinden? all utf-8 kodlamaları bu veya sadece bazıları gibi gösteren mısınız? Bu mümkün mü size kodlamaları yanlış vardı ve zaten utf-8 iken yanlış utf-8 iso8859-1 dönüştürülmüş oldu?

i uzun zaman önce aynı sorun vardı ve bunu kullanarak düzelttim

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15">

Ben arama gün sonra bir çözüm buldu. Benim yorumum zaten gömülü ama olacak ...

  1. Ben php ile bozuk veri almak.

  2. Ben set adları UTF8'i kullanmayın

  3. Benim veri utf8_decode () kullanın

  4. Ben hala UTF8 kümesi adlarını kullanarak değil, benim yeni çözümlenmiş veriler ile benim veritabanını güncellemek

ve işte budur :)