2012-11-27 14 views
9

Na naszej stronie niektórzy użytkownicy komputerów Mac mają problemy podczas kopiowania i wklejania tekstu z plików PDF do TextArea (obsługiwane przez TinyMCE). Wszystkie akcentowane znaki są uszkodzone i stały się na przykład e? dla é, i? dla î itd. Nie mogę odtworzyć tego problemu na komputerze z systemem Windows.PHP: Unikodowany znak i znaki diakrytyczne Unicode

Kiedy napisałem zawartość pliku TextArea na pliku (przed wstawieniem go do bazy danych), właśnie odkryłem, że początkowy różni się wizualnie od tradycyjnego é (w Vim, patrz poniżej).

Visual example of the problem

Rzeczywiście:

// the corrupted é - first line of the screenshot 
echo bin2hex($char); // display 65cc81 

// traditionnal é 
echo bin2hex('é'); // display c3a9 

Po wyszukaniu dużo, jestem tutaj: Wydaje się, że Mac OS kopie Unicode podkreślona znaków jako kombinacja dwóch znaków: w naszym przykładzie e + ́. Do tej pory nie znalazłem żadnego rozwiązania, aby zastąpić uszkodzony é prawdziwym, aby uniknąć e? w bazie danych.

Jestem trochę zdesperowany.

+4

http://unicode.org/reports/tr15/ – hakre

Odpowiedz

8

Proces normalizing the representation to one form or the other nazywa się, no cóż, normalizacją. W PHP nie jest Normalizer class na to, wysyłając wszystkich wprowadzonych przez to jest dobry pomysł:

$input = Normalizer::normalize($input); 

Prawdopodobnie chce unormować w celu utworzenia C Canonical dekompozycji następnie Canonical Kompozycji.

Jeśli ta klasa nie jest dostępna w twoim systemie, jest to Patchwork UTF-8 library.

+0

Hmm, ciekawe, rzeczywiście. Nadal mnie zaskakuje Twoje odpowiedzi ... – shadyyx

+1

Należy zauważyć, że nie ma rzeczywistego uszkodzenia. Rozłożone postacie są całkowicie poprawne. –

+0

@Tino Rzeczywiście. Należy zbadać, dlaczego baza danych lub proces prowadzący do niej * uszkadza * rozłożone postacie. – deceze

0

Jest to parametr konfiguracyjny TinyMCE, który pozwala zdefiniować funkcję do przetwarzania wklejone zawartość przed wprowadzeniem w edytorze: paste_preprocessing

Używając tej funkcji można wymienić specialchars z pożądanej postaci

tinyMCE.init({ 
     ... 
     paste_preprocess : function(pl, o) { 
      // Content string containing the HTML from the clipboard 
      o.content = o.content.replace(/\u2020/, 'x'); // example 
     }, 
     paste_postprocess : function(pl, o) { 
      ... 
     }, 
     ... 
}); 
+1

Pożądaną formą będzie * Singleton * zamiast * Kombinacja sekwencji * Czy dysponujesz biblioteką JavaScript, która sobie z tym poradzi? – hakre

+0

Tak, to jest API tinymce: http://tinymce.moxiecode.com/js/tinymce/docs/api/index.html., Ale konwersja znaków javascript musi być zdefiniowany przez administratora strony w funkcji paste_preprocess – Thariama

+0

Interesujący, ale który t jest nazwą klasy Normalizer? Nie mogę tego znaleźć. – hakre

4

Jest to tylko dodatek do tego, na co @deceze już odpowiedziałeś. W Unicode istnieje wiele sposobów określania tego samego (w sensie równoważności) charakteru.

mieć wspólny przykład tutaj:

65cc81 

To są dwa codepoints Unicode w kodowaniu UTF-8. 65 jest eŁacińska mała litera E (U + 0065) i cc81 jest ́ŁĄCZENIE ostrego AKCENT (U + 0301) (nie mogą być wyświetlane przez przeglądarkę sam, więc wziąłem podmiot HTML).

W Unicode nazywa się to Łącząc sekwencję. Z jakiegoś powodu jednak twoja baza danych go nie obsługuje. Prawdopodobnie dlatego, że kodowanie kolumny nie jest UTF-8 lub połączenie z bazą danych ma z tym problemy.

kanonicznej jest równoważne

c3a9 

jest to pojedynczy kodowy Unicode UTF-8. c3a9 to éLATIN MAŁA LISTA E ZE ŚWIECĄ (U + 00E9). Wygląda na to, że twoja baza danych nie ma problemu z jej obsługą, prawdopodobnie dlatego, że została poprawnie zakodowana na Latin-1/ISO-8859-1 przez połączenie z bazą danych.

Przywołują dwa sposoby przetwarzania danych. Jest to problem w ponownym kodowaniu danych lub problemie przechowywania danych.

Tak długo, jak interesuje cię dekompozycja skomponowanych kodeków kodowanych w Unicode, powinieneś wziąć normalizator opisany w Deceze's answer.

Możesz również zezwolić na zapisywanie w bazie danych UTF-8, a następnie nie powinieneś mieć problemu.

Co więcej, prawdopodobnie powinieneś znormalizować, aby sortowanie i porównywanie danych w bazie danych lub programie działało lepiej. Jak widać, sekwencje binarne różnią się, co może powodować problemy dla wszystkiego, co porównuje na poziomie binarnym.

I rzeczywiście, można zaoszczędzić trochę ruchu :)

+0

Thnak za odpowiedź. Bardzo przydatna prezentacja, wiele się uczę dzięki Tobie! :) –

+1

To miło przeczytać. Również znalazłem ten wpis na blogu, który jest interesujący w moich oczach: [Unicode Normalization] (http://annevankesteren.nl/2009/02/unicode-normalization) - ma kilka linków, niektóre wciąż działają, jeśli chcesz kopać nawet głębiej dla części Unicode. – hakre

+0

Dzięki za link. Po prostu to zrobiłem, a przeczytam to później (w metrze :)) –