2009-05-26 27 views
7

UTF-8 biçiminde saklanan 120.000 satırlık bir MySQL tablom var. Birçok aksan içeren bir alan, ürün adı var. Aynı ada sahip bir ikinci alanı bir URL-dostu forma (ASCII) dönüştürdükten sonra doldurmam gerekiyor. PHP doğrudan UTF-8 işlemek olmadığındaniconv akıllı tırnaklarla "Yasadışı Karakter" verir - onlardan nasıl kurtulur?

, ben kullanıyorum:

 
$value = iconv ('UTF-8', 'ISO-8859-1', $value); 

büyük strstr deyimi ardından ISO-8859-1 Bir adı, dönüştürmek için herhangi bir aksanlı karakter yerine onun unaccented eşdeğeri (à, örneğin, bir) olur.

Ancak orijinal metin isimleri Akıllı tırnaklar girildi ve biri karşı karşıya kalındığında iconv bobinleri - alıyorum:

 
Unknown error type: [8] 

iconv() [function.iconv]: Detected an illegal character in input string 

iconv kullanmadan önce akıllı tırnaklar kurtulmak için, ben denedim gibi üç ifadelerini kullanarak:

 
$value = str_replace('’', "'", $value); 

(€ ™ UTF-8 akıllı tek alıntının ham değeridir â) metin dosyası çok uzun olduğundan, inci bu str_replace en nedenidir e script her zaman için zaman aşımına uğradı.

  1. önce iconv çalışan bir UTF-8 dizesinden Akıllı tırnak (veya geçersiz karakterler), atmak için en hızlı yolu nedir? Ya da, bütün bu sorun için daha kolay bir çözüm var mıdır?

  2. Bir ismin, UTF-8'de, çok sayıda aksanla, ASCII'de doğru olarak yazılmayan, doğru olmayan bir isme dönüştürülmesinin en hızlı yolu nedir? "Link-friendly" ile ne demek istiyorsun?

+2

iconv() 's // TRANSLIT özelliğini denediniz mi? Vurgulu karakterleri okunabilir ASCII eşdeğerlerine dönüştürmelidir. – ceejayoz

+0

Belgelere bakıyorum ama nasıl yardımcı olacağını görmüyorum - eğer iconv() zaten akıllı bir alıntı yaparsa, // TRANSLIT kullanırsam hala boğulmaz mı? –

+0

Bu, "kitlesel strstr deyiminiz" için daha fazla - bu yüzden bir cevap yerine yorum yaptım. – ceejayoz

cevap

2

<a>...</a> etiketleri arasındaki metin herhangi bir şey olabileceğinden, bana mantıklı olan tek yol, her şeyin [a-z-]'a dönüştürüldüğü SO'ların URL'lerine benzeyen "URL dostu" dır.

Yapmak istediğiniz şey buysa, bir karakter kümesi dönüştürme kitaplığı değil, bir çevirisi kitaplığı gerekir. (Geçmişte işi yapmak için iconv() alma şansım olmadı, ama bir süredir denemedim.) translit isimli bir beta PHP uzantısı probably does the job.

PHP kurulumunuza uzantı ekleyemiyorsanız, aynı şeyi yapan bir PHP kütüphanesi aramak zorundasınız. Kullanmamıştım, ancak PHP UTF-8 kitaplığı, ihtiyacın olan gibi bir şey yaptığını farz eddiğim bir utf8_to_ascii kitaplığı uygular.

(Ayrıca, eğer iconv() dediğiniz gibi başarısız olursa, bu, girişinizin aslında geçerli bir UTF-8 olmadığı anlamına gelir, bu nedenle geçerli bir UTF-8'in başka herhangi bir şeyle değiştirilmesiyle ilgili bir miktar sorunun oluşmasına yardımcı olmaz. Bunu geri alabilirim: ephemient's answer doğruysa, gördüğünüz simge hatası çok iyi olabilir çünkü hedef karakter kümesindeki karakterin doğrudan temsili yoktur. Yani, nevermind.)

+0

Soruyu, URL dostu okumak için değiştirdim. PHP'ye uzantı ekleyemiyorum. Önerdiğin translit kütüphaneyi kontrol ettim, ama orijinal çözümümden yaklaşık% 35 daha yavaştı. –

0

MySQL'in kullanımını düşündünüz mü? REPLACE Arıza dizelerini kesme işaretleri olarak değiştirmek için kullanılan işlev, ya da her neyse? "Değiştirilecek dize" kısmını ör. CHAR çağrıları üzerinden CONCAT kullanarak ...

+0

Hatalı dizeleri değiştirmek için str_replace kullanarak başladım, ancak betiği çok fazla yavaşlattı ($ değer = str_replace ('â € ™', '', $ değer); burada as asci gösterimi akıllı tek teklife meydan okuma). CHAR çağrılarında CONCAT tarafından ne demek istediğini açıklayabilir misiniz? –

+0

SQL'de REPLACE yapmayı ve değiştirmeye çalıştığınız alt dizeyi, bayt baytını oluşturmak için CONCAT (CHAR (...),… kullanarak yapmayı önerdim. –

6

Glibc (GNU libiconv) supports//TRANSLIT ve //IGNORE ekler.

 
$ echo $'\xe2\x80\x99' 
’ 
$ echo $'\xe2\x80\x99' | iconv -futf8 -tiso8859-1 
iconv: illegal input sequence at position 0 
$ echo $'\xe2\x80\x99' | iconv -futf8 -tiso8859-1//translit 
' 

Ben iconv PHP tarafından kullanılıyor ne olduğundan emin değilim, ama belgelere //TRANSLIT ve //IGNORE de oraya çalışacağını ima:

Böylece Linux üzerinde, bu gayet güzel çalışıyor.