Valutazione 4.87/ 5 (100.00%) 5838 voti

Condividi:        

Caratteri PHP/MYSQL

Problemi di HTML? Di PHP, ASP, .NET, JSP, Perl, SQL, JavaScript, Visual Basic..?
Vuoi realizzare programmi in C, C++, Java, Ruby o Smalltalk, e non sai da che parte cominciare?
Entra qui e troverai le risposte!

Moderatori: Triumph Of Steel, archimede

Caratteri PHP/MYSQL

Postdi janfri » 10/03/06 09:49

Buongiorno a tutti,
Lavorando al 90% nel mio ufficio, in casa, non ho molte possibilità di confronto e perciò provo a postare un problema che secondo me
è più metodologico che tecnico.
Premessa:
- L'obbiettivo del lavoro è quello di costruire una base web multilingua.
- Poichè di lingue ce ne sono migliaia ci si prefigge di lavorare solo con le lingue europee o comunque le più conosciute (es. inglese, tedesco, spagnolo.. cioè non cirilliche ne arabe o altro.)

Oggetti in gioco:
- browser per la rappresentazione dei dati
- browser per l' immissione dei dati (CMS)
- Database (in questo caso MySql)
- PHP
- Server ?? Non ho capito se un tipo di server od un altro possa incidere

Impostazioni di base per lo svolgimento del progetto:
- charset da utilizzare è il "UTF-8";
- inserimento del charset nell'head delle pagine
- impostazione del database come collation UTF8_general_ci


Risultati:
I dati inseriti vengono gestiti e visualizzati correttamente

Fin qui si direbbe che sto scrivendo solo per dare qualche informazione a chi non ha mai lavorato in multilingua.
Può essere anche gratificante sapere che qualcuno lavora sulle tue informazioni ma purtroppo tutto ciò, che sembra corretto ha un
grande però...

Se andiamo ad analizzare i dati all'interno del database troviamo questa sorpresa.
I caratteri speciali, per esempio le accentante, vengono memorizzati in ascii ??!!!!
esempio Angorè = Angorè.

Si potrebbe pensare che ciò non sia un problema in quanto il browser pensa a gestire la decodifica del carattere.
Questo è vero ma si va incontro a due problematiche che sono poi gli spunti di riflessione veri e propri.

1 - Quando si effettua un backup da un database ad un altro questi caratteri possono determinare delle rotture nelle
stringhe di sql che vengono generate dai comandi di esportazione.
2 - se si prova a leggere il contenuto del db senza passare da una pagina html, quindi senza la dichiarazione di charset,
ci si ritrova esattamente quello che ha memorizzato mysql e cioè è al posto di è

Tutto ciò porta a strassanti sessioni di esportazioni e problematiche di utilizzo dei dati
quando questi occorrono in altri ambiti che non sia una lettura del browser
(es. creazione PDF, esportazione in file txt per applicazioni esterne, ecc.. ec..)

Ho lanciato la palla.. Qualcuno la raccoglie ????

Buon pensiero
:roll:
janfri
Utente Junior
 
Post: 14
Iscritto il: 10/03/06 09:46
Località: Gabicce Mare

Sponsor
 

Postdi archimede » 10/03/06 10:56

L'argomento mi interessa e non credo sia banale come può sembrare a prima vista.

Io non conosco MySQL, ma mi pare strano che
Se andiamo ad analizzare i dati all'interno del database troviamo questa sorpresa.
I caratteri speciali, per esempio le accentante, vengono memorizzati in ascii ??!!!!
Come hai analizzato i dati? Non potrebbe essere un problema di impostazioni del client usato per l'analisi? Oppure il db non è configurato esattamente come tu pensi, magari c'è qualche altra opzione da impostare.

Se invece è proprio così che lavora MySQL, allora il problema mi pare di ancor più difficile soluzione...

Alessandro
archimede
Moderatore
 
Post: 2755
Iscritto il: 07/11/02 12:41
Località: Genova

Postdi Triumph Of Steel » 10/03/06 11:49

non vorrei dire una stupidata, vado a memoria.. ma UTF8 credo non supporti gli accenti...
Avatar utente
Triumph Of Steel
Moderatore
 
Post: 7852
Iscritto il: 22/08/01 01:00

Il client e gli accenti

Postdi janfri » 10/03/06 15:40

Mi fa piacere torvare persone interessate a questo argomento in quanto ritengo che sia spesso sottovalutato.

Per gestire il databse principalmente uso phpmyadmin.
E' con esso che andando a visualizzare e/o modificare una riga di tabella che si riscontra il contenuto reale del campo. Ritengo che non sia una questione di impostazione del client ma piuttosto del charset impostato nel database.

l'UTF8 non supporta gli accenti ? sarebbe gravissimo. :cry: .
Spero che triumph non abbia ragione. Però potrebbe essere proprio quello il motivo dato che ho sempre riscontrato questi problemi sugli accenti.
Ma se fosse così significa che il charset unico per gestire il multilingua occidentale non esiste ?
Ho optato per questo charset perchè nel database puoi impostarne uno e mi sembra non credibile la situazione di costruire un db per ogni linguaggio non trovate ?
janfri
Utente Junior
 
Post: 14
Iscritto il: 10/03/06 09:46
Località: Gabicce Mare

Postdi GAD » 10/03/06 16:26

Se vuoi fare le cose semplicemente credo convenga tenere i dati in modo generico come binary, poi nel momento in cui li stampi non devi fare altro che associare l'encoding e il carattere giusto già nella pagina web o nell'output che ti prefiggi (es nella pagina web metti charset=xxxx)
In questo modo puoi gestire l'output indipendentemente da cosa hai nel database e backup, operazioni su tabelle ecc non danno problemi.
A livello enterprise per applicazioni molto strutturate di solito e' consigliabile gestire multitabelle (una per ogni lingua) discrimando i record in qualche modo es. le persone inglesi sulla tabella inglese, le italiane su quella ita ecc..
.. questo perche' (sempre a livello enterprise) con database tosti tipo oracle e hardware dedicato (come multiprocessori e cluster) si possono lanciare query in multithreading nel caso di ricerca unitaria in tutte le tabelle o query piu' snelle sulla singola tabella (se so a priori che una persona e' inglese lancio la query solo su quella tabella, non su tutte le altre e risparmio parecchio tempo)
Quando l'ultimo albero sarà abbattuto,l'ultimo pesce catturato,l'ultimo fiume avvelenato,
soltanto allora gli uomini si accorgeranno chei soldi non possono essere mangiati
GAD
Moderatore
 
Post: 2184
Iscritto il: 22/09/02 14:36
Località: Nebbiosa

Postdi Triumph Of Steel » 10/03/06 17:28

la soluzione di GAD mi sembra ottima.
Ricordati che puoi sempre usare in PHP

Codice: Seleziona tutto
header ("Content-Type: text/html; charset=CHARSET");


io per esempio mi sono fatto uno script che si prende la lingua del browser e a seconda della lingua carica un charset!
Avatar utente
Triumph Of Steel
Moderatore
 
Post: 7852
Iscritto il: 22/08/01 01:00

Postdi archimede » 11/03/06 09:41

Triumph Of Steel ha scritto:UTF8 credo non supporti gli accenti...
:eeh: http://manuals.thexdershome.com/mysql-4 ... et-Unicode
GAD ha scritto:Se vuoi fare le cose semplicemente credo convenga tenere i dati in modo generico come binary, poi nel momento in cui li stampi non devi fare altro che associare l'encoding e il carattere giusto già nella pagina web o nell'output che ti prefiggi (es nella pagina web metti charset=xxxx)
In questo modo puoi gestire l'output indipendentemente da cosa hai nel database e backup, operazioni su tabelle ecc non danno problemi.
A livello enterprise per applicazioni molto strutturate di solito e' consigliabile gestire multitabelle (una per ogni lingua) discrimando i record in qualche modo es. le persone inglesi sulla tabella inglese, le italiane su quella ita ecc..
Non sono sicuro di capire: cosa vuol dire tenere i dati in modo generico come binary? Nel db devi pur definire un character set: se ne usi uno, ad es., a 7bit credo che inevitabilmente perderai dei dati se cerchi di registrare caratteri a 8bit.

Quanto poi alla gestione di tabelle diverse, non vedo questo come possa risolvere i problemi di character set, a meno che MySQL non ti consenta di definire character set diversi per tabelle diverse.

IMHO, a livello enterprise per applicazioni molto strutturate si dovrebbe definire il db usando un character set che comprenda i caratteri di tutte le lingue che si prevede di supportare.
Triumph Of Steel ha scritto:io per esempio mi sono fatto uno script che si prende la lingua del browser e a seconda della lingua carica un charset!
Quella dell'header credo sia la strada corretta, ma sono un po' perplesso circa la seconda parte: è il browser che si deve adattare ai caratteri che gli mandi (dal db), non viceversa, o sbaglio?

Alessandro
archimede
Moderatore
 
Post: 2755
Iscritto il: 07/11/02 12:41
Località: Genova

Postdi GAD » 11/03/06 11:24

Non sono sicuro di capire: cosa vuol dire tenere i dati in modo generico come binary? Nel db devi pur definire un character set: se ne usi uno, ad es., a 7bit credo che inevitabilmente perderai dei dati se cerchi di registrare caratteri a 8bit.

Se li tieni come binary i caratteri vengono tradotti (col charset corrente di input) nel loro valore binario e aggiunti ad un array nel database. Per lo storing la rappresentazione grafica del singolo carattere non ha piu' senso perche' si lavora su byte. I confronti e tutto il resto delle operazioni vengono effettuate confrontando byte.
Se io inserisco dati con codifica ad 8 bit e il mio aiutante cinese scrive a 7 bit lo storing e' identico , semplicemente a quello a 7 bit viene aggiunto uno 0 davanti e il valore non cambia, poi lo si mette nell'array di byte[] e lo si memorizza.
Il casino nasce nel momento in cui c'e' da fare una query.. se io cercassi nel mio db ipotetico cinese+ita dove tutti i dati sono binari il nome "ciccio"
otterrei dei risultati sfalsati poiche' la c=01010101 (metto a caso) per il charset che ho usato io ad inserire sarebbe la Ç=01010101 cinese.
Stesso valore binario ma signifito differente... quindi troverei n persone in piu' nel mio db di cui solo poche sono effettivamente quelle a cui miravo poiche' gli altri risultati non sono che frutto di una comparazione byte-byte che non ha significato reale quando tradotta nella sua codifica char.
Quindi allargo la possibilità di storing ma mi frego nel momento in cui devo fare query. La soluzione e' semplice, aggiungo un campo nella tabella per tenere traccia della codifica di inserimento.
In questo modo se cerco un cinese cerchero l'array di byte[] + codifica=cinese mentre se cerco un italiano cerchero array di byte[] +codifica italiana.
Stessa cosa la applichero' in output nella pagina web. Se devo stampare risultati comprensibili in cinese assocero' un charset cinese nell'header all'output cinese e i mie dati binari si trasformeranno nel significato per quella lingua.


IMHO, a livello enterprise per applicazioni molto strutturate si dovrebbe definire il db usando un character set che comprenda i caratteri di tutte le lingue che si prevede di supportare.


Vero, ma dipende molto dall'obiettivo prefissato. Se per esempio io ho un hardware multiprocessore che deve servire n uffici.. come un anagrafe multistatale che serve i comuni di ogni stato per esempio, e volessi guardare al punto di vista prestazioni?
Se a priori posso dividere il mio insieme di dati in base ad un discrimnante, la nazionalità della persona per es. e creare n tabelle.
Avro' tante tabelle ma tutte molto piu' snelle (pure la rima ho fatto) e quindi una query di cui conosco la nazionalità della persona mi verrà completata in meno tempo (meno record da confrontare= meno tempo).
In piu' nel discorso dell'hardware multiprocessore potro' lanciare altre n query su tabelle differenti per servire altri n uffici negli altri stati che cercano a loro volta una persona di certa nazionalità.
Se invece devo tenere un database i cui dati sono visibili in entramble le codifiche per tutti gli uffici (tipo db criminale multistato) visto che ogni codifica traduce la rappresentazione grafica ma non il significato reale.. toccherà mettere campi multipli per contenuto e per charset di visualizzazione. Es se devo vedere il nome di un terrorista in arabo e in inglese dovro' avere 2 campi nome (eng, araba) + 2 campi codifica (eng, araba).


Quella dell'header credo sia la strada corretta, ma sono un po' perplesso circa la seconda parte: è il browser che si deve adattare ai caratteri che gli mandi (dal db), non viceversa, o sbaglio?

Sni. Quando tu fai una printf() o usi na funzione che estrae i dati dal db e li mette in un file di testo\pagina html il valore binario dei dati viene tradotto nel carattere delle codifica che hai usato nel database.
Per vederli universalmente pero' devi mettere nell'header della pagina la codifica con cui "chi carica la pagina" deve vedere il testo. Altrimenti anche se i dati che per te avevano un valore e hai stampato secondo quel valore-> per me che sono in cina con altra codifica non avranno senso e li visualizzero' coi miei caratteri e tutti scazzati. Come quando in word si seleziona un testo e si scorrono i caratteri tipo symbols ecc..
Quindi devi sempre mettere nell'intestazione l'encoding per cui il tuo output ha senso e forzare il browser a visualizzare i dati nella struttura che tu immagini.

PS: mai dare un calcio all'ups prima di premere Invia ..c'e' da riscrivere tutto, dho!
Quando l'ultimo albero sarà abbattuto,l'ultimo pesce catturato,l'ultimo fiume avvelenato,
soltanto allora gli uomini si accorgeranno chei soldi non possono essere mangiati
GAD
Moderatore
 
Post: 2184
Iscritto il: 22/09/02 14:36
Località: Nebbiosa

Postdi archimede » 11/03/06 13:09

Perdonami GAD ma la soluzione che tu proponi mi sembra eccessivamente complicata.

Ho fatto alcune ricerche nella documentazione Oracle (che è l'ambiente in cui mi muovo) ed i risultati (per ora parziali, lo ammetto) sembrano corroborare questa mia impressione.

In particolare:
Unicode is a universal encoded character set that enables information from any language to be stored using a single character set. Unicode provides a unique code value for every character, regardless of the platform, program, or language.
(fonte)


Come dicevo, continuerò a documentarmi ma sento che la strada verso un'efficiente gestione di un db multilingua non può essere quella da te indicata.

Alessandro
archimede
Moderatore
 
Post: 2755
Iscritto il: 07/11/02 12:41
Località: Genova

Postdi GAD » 11/03/06 13:42

Beh non e' tanto complicata dai, a certi livelli ci sono cose molto piu' devastanti. Se lavori in oracle pensa ai casotti dei tipi di dato personalizabili e script associabili al tipo di dato (una volta per fare un indice autoincrementante sono diventato cretino :aaah )
Ma questo non e' niente, se inizi a giocare con tibco per far comunicare il db oracle con altre applicazioni allora la faccenda diventa pesante, alla faccia della mia gestione binaria con l'aggiunta di un campo per il charset.

Cmq hai ragione, la mia non e' l'unica soluzione ne' la migliore, per quello ho ripetuto che dipende dallo scopo ,dagli obiettivi, dalle infrastrutture ecc.
Soprattutto pensavo ad una discussione piu' generale, non solo al problema da cui il topic e' nato di mysql.
Quella dell'unicode e' la stessa cosa del workaround che uso io. Se imposti un campo unicode non fai altro che salvare il tipo di carattere con cui immetti un dato. Quindi hai dato + tipo_carattere. Ora il tipo_carattere lo puoi mettere in modo implicito dicendo che dato e' unicode oppure in modo esplicito mettendo un parametro addizionale nella tabella, sempre di quel dato si tratta.
La differenza sostanziale e' che unicode ti agevola il trattamento dentro al database e la stampa perche' e' a carico del pc client riconoscere e tradurre il testo in base ai caratteri installati.
Dall'altra parte pero' hai la pecca del contenuto che cmq puoi risolvere solo usando doppi campi o doppie tabelle. (nb: non sempre, solo per certi dati)
Nel mio database criminale ipotetico che deve visualizzare il nome dei terroristi sia in inglese che in arabo devo salvare il nome per forza in 2 modalità perche' indipendentemente dai caratteri il nome "cic bdul" arabo si traduce in "ciccio ahbdul" inglese. Cioe' cambia proprio il contenuto.
Quando l'ultimo albero sarà abbattuto,l'ultimo pesce catturato,l'ultimo fiume avvelenato,
soltanto allora gli uomini si accorgeranno chei soldi non possono essere mangiati
GAD
Moderatore
 
Post: 2184
Iscritto il: 22/09/02 14:36
Località: Nebbiosa

Postdi archimede » 11/03/06 14:16

GAD ha scritto:(una volta per fare un indice autoincrementante sono diventato cretino :aaah )
Vero, non è molto intuitivo ma nemmeno complicato, una volta che sai come si fa. ;)
...poi ha scritto:Quella dell'unicode e' la stessa cosa del workaround che uso io. Se imposti un campo unicode non fai altro che salvare il tipo di carattere con cui immetti un dato. Quindi hai dato + tipo_carattere. Ora il tipo_carattere lo puoi mettere in modo implicito dicendo che dato e' unicode oppure in modo esplicito mettendo un parametro addizionale nella tabella, sempre di quel dato si tratta.
Questo vale per qualsiasi characterset, non solo per Unicode (almeno così io ho capito). Cioè nel db, alla fine della fiera, ci finiscono sempre dei bytes: questi bytes rappresentano determinati caratteri in base al characterset impostato a livello di db, non nella singola tabella.
...quindi ha scritto:La differenza sostanziale e' che unicode ti agevola il trattamento dentro al database e la stampa perche' e' a carico del pc client riconoscere e tradurre il testo in base ai caratteri installati.
Qui non ti seguo più... I caratteri installati dove? Se il mio db registra i dati in UTF-8 sarà compito del programmatore (o del web server) comunicare al client che i dati che sta per ricevere sono in quel characterset. Analogamente, se i miei dati sono in un altro characterset dovrò comunque comunicarlo al client affinchè i dati siano interpretati correttamente. Mi sfugge insomma dove sta l'agevolazione, se non nel fatto che con Unicode posso gestire un set di caratteri più ampio.
...infine ha scritto:Dall'altra parte pero' hai la pecca del contenuto che cmq puoi risolvere solo usando doppi campi o doppie tabelle. (nb: non sempre, solo per certi dati)
Nel mio database criminale ipotetico che deve visualizzare il nome dei terroristi sia in inglese che in arabo devo salvare il nome per forza in 2 modalità perche' indipendentemente dai caratteri il nome "cic bdul" arabo si traduce in "ciccio ahbdul" inglese. Cioe' cambia proprio il contenuto.
Beh, ma in questo caso stiamo parlando di due dati diversi, non vedo il nesso con il characterset. E' ovvio che le traduzioni di un testo in lingue diverse debbano essere fisicamente distinte dentro al db.

Alessandro
archimede
Moderatore
 
Post: 2755
Iscritto il: 07/11/02 12:41
Località: Genova

Postdi GAD » 11/03/06 19:23

cazzarola non riesco a spiegarmi, mea culpa!!
Prova a vedere qui come viene spiegato lo storing dell'unicode e dei vari charset
http://www.joelonsoftware.com/articles/Unicode.html
e qui
http://www.cs.tut.fi/~jkorpela/chars.html

Quando ero a scuola mi facevano sto esempio.
Se salvi in charset non fai altro che scrivere l'indice del carattere usato nel suo charset.
Es a=1 b=2 c=3 se scrivo "abc" nel mio db salvero' un'array che contiene gli indici [1,2,3].
Ora, quando tu direzioni l'output da qualche parte come una pagina html le informazioni le scrivi già in modo corretto dal db alla tua printf tramite l'associazione charset-indici array ovvero torni da [1,2,3] ad "abc".
Il client che pero' rilegge la pagina dall'altra parte del mondo ha solo delle stringhe che tu hai già stampato su file. Deve sapere come interpretarle, ossia sapere il charset con cui tu hai scritto sulla pagina. Per questo all'inizio del file html si mette il charset da utilizzare.
La stessa cosa accade coi font nei documenti word o sempre nelle pagine html. Se non metti l'informazione del font da utilizzare per reinterpretare la pagina ma metti solo il tuo output (che va bene per te localemente) potrà essere letto in modo identico solo da chi ha installo stesso charset e stessi font.
Quando l'ultimo albero sarà abbattuto,l'ultimo pesce catturato,l'ultimo fiume avvelenato,
soltanto allora gli uomini si accorgeranno chei soldi non possono essere mangiati
GAD
Moderatore
 
Post: 2184
Iscritto il: 22/09/02 14:36
Località: Nebbiosa

Postdi archimede » 13/03/06 09:40

GAD ha scritto:cazzarola non riesco a spiegarmi, mea culpa!!
Probabilmente sono io un po' duro di comprendonio, don't worry.
GAD ha scritto:Prova a vedere qui come viene spiegato lo storing dell'unicode e dei vari charset
Grazie per i links.

Oggi sono forse un po' più lucido e, rileggendo il tuo ultimo messaggio, mi pare che in fondo stiamo dicendo la stessa cosa.

Un db che registra le stringhe in formato UTF-8 è in grado di gestire praticamente qualsiasi carattere di qualsiasi lingua.

I problemi sorgono nel momento in cui, una volta estratte le informazioni, queste vengo visualizzate da qualche parte, cioè inviate a un client di qualche tipo. Se il client di destinazione non sa che si tratta di UTF-8, userà un charset di default che, se diverso, genererà un output potenzialmente incomprensibile.

Sarà quindi compito del programmatore:

a) sapere quale character set il db usa e dimensionare i campi delle tabelle in maniera appropriata
b) fare in modo che il character set usato dal db venga comunicato al client prima che questi visualizzi i dati

Ci siamo oppure mi manca ancora qualche pezzo?

Alessandro
archimede
Moderatore
 
Post: 2755
Iscritto il: 07/11/02 12:41
Località: Genova

Postdi GAD » 13/03/06 09:45

Approvato :D
Quando l'ultimo albero sarà abbattuto,l'ultimo pesce catturato,l'ultimo fiume avvelenato,
soltanto allora gli uomini si accorgeranno chei soldi non possono essere mangiati
GAD
Moderatore
 
Post: 2184
Iscritto il: 22/09/02 14:36
Località: Nebbiosa

Postdi janfri » 16/03/06 11:07

Buongiorno,
Mi scuso per l'assenza dalla discussione ma sono stato a Bari.

Ho letto tutti i vostri commenti, fatto delle prove e sono a
proporvi una possibile soluzione in riferimento ad un progetto multilingua :

- Alla costruzione del database ocorre indicare il charset massimo contenitivo delle lingue in riferimento al progetto che si vuole realizzare

- Ogni contenuto che abbisogna del supporto multilingua potrebbe essere realizzato attraverso la costruzione di due tabelle corellate tra loro attraverso id univoco e lingua.

es. tabella autori :

documents (tabella primaria):
iddoc id documento
idedit id editore

documents_lang (tabella secondaria multilingua):
iddoc id docmento
titledoc titolo documento
abstrdoc abstrac documento
langdoc lingua doc

Così facendo, anche se per uno stesso documento si hanno più verisoni di lingua, attraverso SQL si lavorerà sampre con solo una riga per ogni documento ed il codice di estrazione dei dati è sempre lo stesso

- Per l agestione dei dati attraverso il browers, come avete detto, sia per lettura che per scrittura: gestire il codice charset riferito alla lingua che si deve utilizzare.

Secondo voi è corretto o qualcosa ancora non trona ?

P.S. per gado.. Si è parlato disalvare i dati in binario. Significherebbe
indicare a database il charset binary ???

Buon lavoro a tutti
janfri
Utente Junior
 
Post: 14
Iscritto il: 10/03/06 09:46
Località: Gabicce Mare


Torna a Programmazione


Topic correlati a "Caratteri PHP/MYSQL":


Chi c’è in linea

Visitano il forum: Nessuno e 6 ospiti