2012-11-27 10 views
9

Nel nostro sito Web, alcuni utenti Mac hanno problemi quando copiano e incollano il testo da file PDF in una TextArea (gestita da TinyMCE). Tutti i caratteri accentati sono danneggiati e sono diventati ad esempio e? per un é, i? per un î, ecc. Non riesco a riprodurre questo problema con un computer Windows.PHP: carattere accentato e segni diacritici

Quando ho scritto il contenuto di TextArea su un file (prima di inserirlo nel database), ho appena scoperto che l'iniziale è visivamente diversa da quella tradizionale é (su Vim, vedi sotto).

Visual example of the problem

Infatti:

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

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

Dopo aver cercato un sacco, eccomi qui: Sembra che Mac OS copie Unicode caratteri accentuato come una combinazione di due caratteri: nel nostro esempio, e + ́. Finora, non ho trovato alcuna soluzione per sostituire corrotto é con quello reale, per evitare e? nel database.

E io sono un po 'disperata.

+4

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

risposta

8

Il processo di normalizing the representation to one form or the other viene chiamato, beh, normalizzazione. In PHP c'è la Normalizer class per questo, l'invio di tutti gli input attraverso di essa è una buona idea:

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

È probabile che vuole normalizzare per formare C, Canonical decomposizione seguito da Composizione Canonical.

Se tale classe non è disponibile sul sistema, è disponibile lo Patchwork UTF-8 library.

+0

Hmm, interessante, anzi. Ancora mi sorprende dalle tue risposte ... – shadyyx

+1

Va notato che non c'è corruzione effettiva. I personaggi decomposti sono perfettamente validi. –

+0

@Tino davvero. Dovrebbe essere studiato il motivo per cui il database o alcuni processi che portano ad esso * corrompono * i caratteri scomposti. – deceze

0

C'è un parametro di configurazione TinyMCE che consente di definire una funzione per elaborare il contenuto incollato prima dell'inserimento nel l'editor: paste_preprocessing

Usando questa funzione è possibile sostituire i specialChars con la forma desiderata

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

La forma desiderata sarebbe il * Singleton * invece della * Combinazione di sequenza * Hai a portata di mano una libreria javascript che si occupa di questo? – hakre

+0

sì, è l'API tinymce: http://tinymce.moxiecode.com/js/tinymce/docs/api/index.html. Ma la conversione dei caratteri javascript deve essere definito dall'amministratore del sito nella funzione paste_preprocess – Thariama

+0

Interessante, ma wha t è il nome della classe Normalizer? Non ho potuto trovarlo. – hakre

4

Questo è solo in aggiunta a ciò che @deceze ha già risposto. Esistono molti modi in Unicode per specificare lo stesso carattere (nel senso dell'equivalenza).

Hai un esempio comune qui:

65cc81 

che sono due codepoints Unicode nella codifica UTF-8. 65 è elatino: lettera E (U + 0065) e cc81 è ́COMBINAZIONE DI ACUTA ACCENT (U + 0301) (che non può essere visualizzato solo dal browser, così ho preso l'entità HTML).

In Unicode viene chiamato Combinazione sequenza. Per qualche ragione, tuttavia, il tuo database non lo supporta. Probabilmente perché la codifica della colonna non è UTF-8 o la connessione al database ha problemi con essa.

Si è canonicamente equivalenti a

c3a9 

Questo è un singolo codepoint Unicode UTF-8 codifica. c3a9 è éLETINA PICCOLA LETTERA E CON ACUTO (U + 00E9). Sembra che il tuo database non abbia problemi a risolverlo, probabilmente perché è stato ricodificato in Latin-1/ISO-8859-1 tramite la connessione al database.

Quindi vengono in mente due modi di gestire i dati. È un problema nella ricodifica dei dati o un problema nella memorizzazione dei dati.

Fintanto che si è interessati alla decompilazione delle sequenze codepoint composte, è necessario prendere il normalizzatore delineato in Deceze's answer.

È inoltre possibile consentire l'archiviazione di UTF-8 nel database e quindi non si dovrebbe avere un problema.

Inoltre, si dovrebbe probabilmente normalizzare comunque in modo che l'ordinamento e il confronto dei dati nel database o nel programma funzioni meglio. Come puoi vedere, le sequenze binarie differiscono e possono causare problemi a tutto ciò che si confronta a livello binario.

E certo, risparmiare un po 'di traffico :)

+0

Thnak per la tua risposta. Presentazione molto utile, imparo molto grazie a te! :) –

+1

Che bello da leggere. Inoltre ho trovato questo post del blog che è interessante ai miei occhi: [Normalizzazione Unicode] (http://annevankesteren.nl/2009/02/unicode-normalization) - ha alcuni link in più, alcuni ancora funzionanti se vuoi scavare anche più profondo per la parte unicode. – hakre

+0

Grazie per il link. L'ho solo preso in giro e lo leggerò più tardi (in metropolitana :)) –

Problemi correlati