Gå til innhold

Konvertere UTF-8 Unicode til ASCII?


Anbefalte innlegg

Som topic sier, så lurer jeg fælt på hvordan jeg skal få til dette. Jeg har en database hvor jeg har lagret alt innhold i UTF-8 og konvertert norske bokstaver til html-lesbar-unicode.

eksempel:
Bjørn = Bj{ø}rn

Når data hentes ut fra databasen, vil nettleseren rendre unicode-tegnene til ascii, men i kildekoden er spesialtegnene fremdeles unicode. Noen som har tips til hvordan jeg kan få konvertert dem til ascii selv, slik at det blir seende slik ut i kildekoden også? Jeg har kikket i php-manualen, og funnet ut at funksjonen html_entity_decode() burde klare jobben - men jeg får det allikevel ikke til..

 

På forhånd, takk :)

 

//edit: måtte innkapsle unicode-en i klammer for å forhindre browseren i å rendre den..

Endret av v3g4rd
Lenke til kommentar
Videoannonse
Annonse

Hvis jeg lagrer tegnene som æ, ø, eller å i databasen og deretter skal hente dem frem igjen - ender det opp med at ø'en blir seende noe slik ut: "Â,,".

 

Jeg har også prøvd å lagre tegnene i databasen som ISO-8859-15 html-entities ved å bruke {ø} som ø, men heller ikke da fungerer det å bruke html_entity_decode(),.. Vil anta at det har noe med denne bestemte Apache-serveren å gjøre - for det går uten problemer på den jeg har kjørende lokalt.

Lenke til kommentar

Du benytter hex-decimal referanser som "»";

 

Denne funksjonen fungerer kun med decimal-referanser som "È";

 

Det står i kommentarene til funksjonen

http://no2.php.net/manual/en/function.mb-d...mericentity.php

 

Løsningen er konsekvent å benytte decimal-referanser. Du må være forsiktig med NULL, <, >, ", osv., så lag en konverteringstabell som kun konverterer sikre tegn.

Lenke til kommentar
Hvis jeg lagrer tegnene som æ, ø, eller å i databasen og deretter skal hente dem frem igjen - ender det opp med at ø'en blir seende noe slik ut: "Â,,".

 

Jeg har også prøvd å lagre tegnene i databasen som ISO-8859-15 html-entities ved å bruke {ø} som ø, men heller ikke da fungerer det å bruke html_entity_decode(),.. Vil anta at det har noe med denne bestemte Apache-serveren å gjøre - for det går uten problemer på den jeg har kjørende lokalt.

 

Du har trolig en tegnsettskonflikt hvis html_entitiy_decode ikke fungerer på ø. Du kan forsøke å mate funksjonen med relevante tegnsett og se om det hjelper.

http://no2.php.net/manual/en/function.html-entity-decode.php

 

Det finnes en konverterings funksjon for tegnsett også:

http://no2.php.net/manual/en/function.mb-c...rt-encoding.php

Jeg har ikke testet denne mot tegn som eksisterer i kilde- med ikke i destinasjons-tegnsettet.

 

Du kan også forsøke med å teste om strengen har lovlig koding

http://no2.php.net/manual/en/function.mb-check-encoding.php

 

Litt tregt men hva med:

<?php
$string = 'Bjørn';
$string = htmlentities(urlencode($string));
echo $string;
?>

 

Hvis du sjekker hva disse funksjonene gjør, vil du se at dette ikke fungerer pr. definisjon.

 

Se på definisjonen til urlencode.

http://no2.php.net/manual/en/function.urlencode.php

Return Values

 

Returns a string in which all non-alphanumeric characters except -_. have been replaced with a percent (%) sign followed by two hex digits and spaces encoded as plus (+) signs. It is encoded the same way that the posted data from a WWW form is encoded, that is the same way as in application/x-www-form-urlencoded media type. This differs from the » RFC 1738 encoding (see rawurlencode()) in that for historical reasons, spaces are encoded as plus (+) signs.

 

Sammenlikner du dette med html_decode_entities

http://no2.php.net/manual/en/function.html-entity-decode.php

html_entity_decode() is the opposite of htmlentities() in that it converts all HTML entities to their applicable characters from string .

 

Dette er to vilt forskjellige ting.

 

Hvis du tar en titt på tabellen som htmlentities benytter vil du finne at det kun er snakk om tegn opp til 0xff, samt at det her kun er snakk om ett begrenset utvalg av entitene som er definert for html4.01.

 

Hva med å bare bruke riktig tegnsett både i databasen og visning?

Dersom du bruker utf-8 i databasen og utf-8 når du viser siden så blir det kos skal du se.

 

Ikke alle web-hoteller tillater bruker å endre tegnsett på databasen, php, eller begge deler.

 

Dette er i og for seg ikke noe enormt problem hvis php er konfigurert med støtte for multibyte string funksjonalitet.

 

utf-8 til iso-8859-15

utf-8 til decimal referanser, dvs. alt over 0xff:

mb_encode_numericentity

Konverter utf-8 til iso-8859-15

mb_convert_encoding

 

iso-8859-15 til utf-8

konverter iso-8859-15 til utf-8

mb_convert_encoding

erstatt referanser med tegn, dvs. alt over 0xff:

mb_decode_numericentity

 

htmlentities og html_entities_decode kan håndtere alt under 0xff på normal måte.

 

Det hele blir selvfølgelig mye mer elegant med utf-8 støtte i php og database, men det er ganske langt igjen til php kan kalle seg ett språk med full støtte for utf-8, da en haug av funksjoner ikke støtter multibyte tegnsett men kun iso-8859-1.

Lenke til kommentar
Det hele blir selvfølgelig mye mer elegant med utf-8 støtte i php og database, men det er ganske langt igjen til php kan kalle seg ett språk med full støtte for utf-8, da en haug av funksjoner ikke støtter multibyte tegnsett men kun iso-8859-1.

Beste av det hele er jo at PHP6 skal bruke UTF16 internt uten at jeg finner noen god grunn til å gjøre det istedenfor UTF8.

Lenke til kommentar
Det hele blir selvfølgelig mye mer elegant med utf-8 støtte i php og database, men det er ganske langt igjen til php kan kalle seg ett språk med full støtte for utf-8, da en haug av funksjoner ikke støtter multibyte tegnsett men kun iso-8859-1.

Beste av det hele er jo at PHP6 skal bruke UTF16 internt uten at jeg finner noen god grunn til å gjøre det istedenfor UTF8.

 

Da slipper de å skrive alt på nytt nok en gang når utf-8 blir for trangt.

Lenke til kommentar
Det hele blir selvfølgelig mye mer elegant med utf-8 støtte i php og database, men det er ganske langt igjen til php kan kalle seg ett språk med full støtte for utf-8, da en haug av funksjoner ikke støtter multibyte tegnsett men kun iso-8859-1.

Beste av det hele er jo at PHP6 skal bruke UTF16 internt uten at jeg finner noen god grunn til å gjøre det istedenfor UTF8.

 

Da slipper de å skrive alt på nytt nok en gang når utf-8 blir for trangt.

Tror du misforstår litt. UTF8 og UTF16 dekker såvidt jeg veit eksakt de samme tegnene. Forskjellen er blant annet at UTF8 er ASCII-kompatibel (riktignok mulig det var tegn 1-128), og at disse tegnene fortsatt bare tar en byte. UTF16 er ikke ASCII-kompatibel og vil alltid bruke 2 eller 4 byte pr. tegn. UTF8 på den andre siden kan bruke 1, 2, 3 eller 4 byte pr. tegn.

 

Etter min mening gir UTF16 mer problemer enn fordeler. Dvs. jeg sliter egentlig veldig med å se noen fordel. Blant annet må de jo med UTF16 slite med koselige ting som BOM mens med UTF8 er det jo fortsatt byte-basert. Det er såklart mulig det tror mange vil bruke det til språk som krever tegn i U+0800 og oppover (f.eks kinesisk, japansk o.l). Dette vil jo kreve 3 byte kontra 2byte i UTF16, men på den andre siden krever tegn under U+0080 (som i bunn og grunn er ASCII-tegn og derfor f.eks mellomrom) 2byte i UTF16 og 1 i UTF8, så noen praktisk forskjell blir det aldri. Nei, det der skjønner jeg fint lite av må jeg ærlig innrømme :hmm:

 

Red.: Hvis noen skulle sitte på en genial forklaring for hvorfor velge UTF16, så hyl ut :)

Endret av Ernie
Lenke til kommentar
Det hele blir selvfølgelig mye mer elegant med utf-8 støtte i php og database, men det er ganske langt igjen til php kan kalle seg ett språk med full støtte for utf-8, da en haug av funksjoner ikke støtter multibyte tegnsett men kun iso-8859-1.

Beste av det hele er jo at PHP6 skal bruke UTF16 internt uten at jeg finner noen god grunn til å gjøre det istedenfor UTF8.

 

Da slipper de å skrive alt på nytt nok en gang når utf-8 blir for trangt.

Da er dessverre UTF16 for trangt også, det er ingen forskjell på hvor mange tegn de kan lagre, bare hvor mye plass de bruker for de forskjellige kodetegnene.

 

Jeg skulle tippe at PHP valgte UTF16 pga. av noen interne greier, kanskje mtp. binærdata <-> typeløshet.

Uansett, sakset dette fra UTF-8-artikkelen til wikipedia:

Compared to UTF-16

 

Advantages

  • Byte values of 0 (The ASCII NUL character) do not appear in the encoding unless U+0000 (the Unicode NUL character) is represented. This means that standard C library string functions (such as strcpy()) that use a null terminator will not incorrectly truncate strings.
  • Since ASCII characters can be represented in a single byte, text consisting of mostly diacritic-free Latin letters will be around half the size in UTF-8 than it would be in UTF-16. Text in many other alphabets will be slightly smaller in UTF-8 than it would be in UTF-16 because of the presence of spaces.
  • Most existing computer programs (including operating systems) were not written with Unicode in mind, except Windows NT and successive operating systems. Using UTF-16 with them while maintaining compatibility with existing programs requires every system API, library function, and structure that takes a string to be duplicated. UTF-8 only requires APIs that specially treat bytes with the high bit set to be duplicated.
  • In UTF-8, characters outside the basic multilingual plane are not a special case. UTF-16 is often mistaken to be constant-length, leading to code that works for most text but suddenly fails for non-BMP characters. Retrofitting code tends to be hard, so it's better to implement support for the entire range of Unicode from the start.
  • UTF-8 uses a byte as its atomic unit while UTF-16 uses a 16-bit word which is generally represented by a pair of bytes. This representation raises a couple of potential problems of its own.
    When representing a word in UTF-16 as two bytes instead of one 16-bit word, the order of those two bytes becomes an issue. A variety of mechanisms can be used to deal with this issue (for example, the Byte Order Mark), but they still present an added complication for software and protocol design.
  • If UTF-16 is interpreted as individual bytes instead of 16-bit words and an odd number of bytes are removed from the beginning of UTF-16-encoded text, the result will be either invalid UTF-16 or completely meaningless text. In UTF-8, if part of a multi-byte character is removed, only that character is affected and not the rest of the text.

Disadvantages

  • Characters above U+0800 in the BMP use three bytes in UTF-8, but only two in UTF-16. As a result, text in [for example] Chinese, Japanese or Hindi takes up more space when represented in UTF-8. However, this disadvantage is partly offset by the fact that characters below U+0080 (Latin letters, numbers and punctuation marks, space, carriage return and line feed) that frequently appear in those texts take only one byte in UTF-8 while they take two bytes in UTF-16.
  • Due to the issues raised in the "Overlong forms, invalid input, and security considerations" section above, extra care is needed to verify the validity of the encoding format of UTF-8. This is less of an issue for UTF-16 where only the validity of the supplementary code points is needed.

Lenke til kommentar
Folk hadde spart seg så utrolig mye arbeid ved å bruke det samme tegnsettet over hele fjøla.. Kjør utf-8 i database og php filer så sparer du deg selv for utrolig mye bryderi!

Ja, men det er dessverre langt fra enkelt, og ærligtalt er det nok mer bryderi for de som ikke innehar litt kunnskap. Hvordan sjekker du f.eks lengde uten mbstring? Hvordan konverterer man tegn til store og små bokstaver? strlen, strtolower og strtoupper vil fungere, men bare på første halvdelen av ASCII. Så har man jo alltids funksjoner som substr som overhode ikke fungerer straks man får multibyte tegn.

 

En annen ting er at utf8_encode og utf8_decode aldri i verden skal brukes når man jobber med utf8. Høres veldig selvmotsigende, eller hva? Vel, funksjonene fungerer bare for ISO-8859-1 encoded som UTF8. Dvs. alt annet en ISO-8859-1-tegn blir til ?, og kan følgelig ikke kodes tilbake til UTF8. Det er det nok langt fra alle som er klar over.

Lenke til kommentar
Da er dessverre UTF16 for trangt også, det er ingen forskjell på hvor mange tegn de kan lagre, bare hvor mye plass de bruker for de forskjellige kodetegnene.

 

Jeg skulle tippe at PHP valgte UTF16 pga. av noen interne greier, kanskje mtp. binærdata <-> typeløshet.

Uansett, sakset dette fra UTF-8-artikkelen til wikipedia:

 

Disse tegnsett greine er til å bli sprø av. Dette var jo en lei blemme fra min side, men det finnes så mye synsing rundt dette temaet at eneste utvei for meg blir å lese ett par bøker om temaet. Det blir vel som det ble med html og css, at jeg ender opp med å nidlese deffen, samt litt støtteliteratur.

 

For ordens skyld støtter ikke php5 mer enn til U+FFFF, samt at mb_decode_numericentity/mb_encode_numericentity ikke blokkerer tegn som er ulovlige i henhold til tegnsett deffen. Det ser ut for meg at eneste mulighet til å gjøre dette riktig er å lese seg opp på deffen, da jeg ikke finner andre solide kilder på dette temaet.

 

Noen som har lest en god og oppdatert bok om temaet?

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...