Niels Gamborgs online notesbog

PHP og dansk tegnsæt. Æ, ø og å fejl. Fra utf-8 til ISO-8859-1

marts 2nd, 2008. Kategori: Webudvikling

Det er min 3. artikel om danske tegnsæts problemer. Igen efter at have oplevet fejl med de danske specialtegn: æ, ø og å. Det er det danske tegnsæt latin1, der driller.

Den tekniske betegnelse for latin1 tegnsættet er ISO-8859-1 eller ISO-8859-15. Og når vi definere vores tegnsæt som et latin1 tegnsæt skal vi bruge de tekniske navne.

PHP. Fra utf-8 til ISO-8859-1

Jeg havde loadet noget XML ind på en webside i form af et RSS feed. Jeg brugte simplexml_load_file() funktionen til denne opgave.  Simple_load_xml leverer XML’en med utf-8 tegnsæt, og det giver problemer, når min hjemmeside er kodet med ISO-8859-1 tegnsæt.  Både overskrifter og indhold var ulæseligt på grund af manglende æ’er, ø’er og å’er.

Heldigvis var løsningen nær, php-funktionen: utf8_decode().

utf8_decode($minTekst);

utf8_decode tager en streng og omdanner den fra utf-8 til ISO-8859-1/latin1. Det kan næsten ikke blive mere simpelt. Og så virker det.

Et eksempel med uft8_decode()

Her er et lidt mere komplekst eksempel fra det virkelige liv.  Scriptet henter et RSS feed fra DR’s kultur sektion.

  <?php
  
   // RSS feeden hentes. Gemmes som obejct i $feed
   $feed = simplexml_load_file(‘http://www.dr.dk/nyheder/service/feeds/kultur’);
   

   //channel og item nodes løbes igennem.
   //Channel er parent, her hentes oplysninger om RSS-feeden
   //Item er child og har selv flere children som feks: title, description, pubDate og link
   //alt kørt igennem utf8_decode() Der returner iso ISO-8859-1

   foreach($feed->channel as $channel){
    print utf8_decode(“Kanal:<a href='{$channel->link}’> {$channel->title}</a><br/>”);
    foreach($feed->channel->item as $item){
      print utf8_decode(“<a href='{$item->link}’>{$item->title}</a><br/>”);
      print utf8_decode(“{$item->pubDate} <br/>”);
      print utf8_decode(“{$item->description} <br/><br/>”);
      } 
   }
   
  ?>

utf8_decode funktionen er brugt på alle print komandoerne, og tegnsætsproblemet er løst … for denne gang. 😉

Skift tegnsæt med iconv()

Hvis ovenstående ikke løste dit tegnsæt problem med de danske bogstaver,  kan du istedet bruge php-funktionen iconv(). iconv-funktionen konverterer mellem forskellige tegnsæt. Og man kan vel og mærke frit vælge de tegnsæt man vil konvertere imellem.

Vil man f.eks. konverterer mellem det danske ISO-8859-1/latin1 tegnsæt og utf-8, ser løsningen sådan ud:

iconv ( (“ISO-8859-1”, “UTF-8”, $minTekst);)

Jeg har f.eks. brugt denne konverterings metode til at finde det rette tegnsæt efter at mine æ, ø og å’er var blevet ødelagt af et AJAX kald. Netop AJAX kan være særlig drilsk, så det kan det være nødvendigt at eksperimentere med forskellige løsninger.

 Se også min tutorial til en simpel RSS reader med PHP

  1. 20 Responses to “PHP og dansk tegnsæt. Æ, ø og å fejl. Fra utf-8 til ISO-8859-1”

  2. By Kim Andersen on mar 8, 2008

    Smart metode Niels. Jo flere “små” funktioner og smarte tricks der kommer om det danske tegnsæt jo bedre.
    Som Jes sagde fredag: “Det er surt at programmere til danskere…”

  3. By Martin on mar 17, 2008

    utf_decode og encode for den sags skyld er altid godt, men man skal bare lige passe på hvis en streng kan være begge dele (oplever vi tit når vi loader xml fra 3.parts)

  4. By Niels on mar 17, 2008

    Tak for tippet Martin. Den problematik kendte jeg ikke.

    Endnu en mulig fejlkilde ved tegnsætsproblemer.

  5. By Christoffer on jan 22, 2009

    Mange tak for denne artikel. Har gennempløjet nettet de seneste to dage uden at finde en løsning på mit problem før jeg kom hertil.

  6. By Niels on jan 23, 2009

    Superfedt du kunne bruge artiklen, Christoffer. Og mange tak for feedbacken. 🙂

    Problemer med tegnsættet er desværre sjældent trivielle at løse, da der ofte er flere kilder til fejlen.

  7. By kim on jan 29, 2009

    kan man ikke også bare i sin head på siden skrive:

  8. By Niels on jan 29, 2009

    Det tror jeg bestemt ikke er nok. 😉

    Nej, spøg til side. Det ser ud til at hele din kommentar af en eller anden grund ikke er kommet med.

  9. By kim on jan 29, 2009

    hehe.. skrev noget html code, men det er ikke kommet med.
    skal man skrive noget bestemt for at få kode vist.

  10. By Niels on jan 30, 2009

    Pga sikkerhed er det meget begrænset hvad man kan poste af HTML tags.

    Men du kan istede bruge html specialcahracters fx:

    & lt;html& gt;

    hvor du bare udelade mellemrummet mlm & og det efterfølgende tegn. Så bliver det til:

    <html>

  11. By Ras on mar 31, 2009

    Lækkert. Jeg fandt løsningen på mit problem her.

  12. By Niels on mar 31, 2009

    Godt du kunne bruge det, Ras. Og tak for tilbagemeldingen. 🙂

  13. By Martin on jul 28, 2009

    Aha!.. utf8_decode
    THANK YOU SO MUCH!!!.. det var lige den løsning jeg søgte.. efter at have søgt rundt i 3 timer!!! Hvor skulle jeg vide fra at XML automatisk blev konverteret til UTF8.. Graa!..

    Tak Niels! :o)

    Mvh. Martin

  14. By Niels on jul 28, 2009

    Glad for at kunne hjælpe, Martin.

    Det værste ved diverse tegnsætsproblemer er, at de kan være både ulogiske og komplicerede at løse.

    Ofte må man famle sig lidt frem for at finde den rigtige løsning. Men jo flere muligheder man har at vælge imellem, jo lettere er det selvfølgelig at finde en der virker. 🙂

  15. By Lone on nov 11, 2009

    Hmm, Har I drenge nogensinde tænkt over det der står i velformede XML-dokumenter:

    der kan jo osse stå andre ting end utf-8, men tjek hellere http://www.w3schools.com/XML/xml_encoding.asp

    Nu kender jeg ikke lige utf8_decode(), men mon ikke den er skidt til noget med headeren

    ?

    Anyway, ja tegnsæt er noget skidt hvis man ikke ved hvad bytes der kommer, men med XML kan og bør det angives. Ellers er afsender en… 🙂
    Mine 2€ 😀

  16. By Hr Hansen on jan 3, 2010

    Husk at der er tre ting der skal stemme overens i det svar der sendes til klienten (browseren):

    1) den reelle kodning af dokumentet (iso-8859-1, utf-8 osv)
    2) charset i Content-Type (http-header)
    3) charset i Content-Type (meta-tag)

  17. By Lauritz on apr 4, 2010

    Hej Niels. Tak for alle de gode råd.

    Jeg kan stadig ikke finde ud af dette mareridt. Jeg har en hjemmeside som er lavet med php includes i css og jeg kan absolut ikke få den til, at vise mine danske tegn. Har du nogen idé til, hvad jeg kunne gøre?

    Jeg forstår ikke denne artikel 🙂

    Mvh
    Lauritz

  18. By Asser on maj 6, 2010

    Du har officielt lige redet min dag! utf8_decode() er temmelig praktisk når javascript og ajax ikke vil spytte ting ud som iso-8859-1. Tak for artiklen

  19. By keld on feb 4, 2011

    jeg koder til iphone lige nu, men nogle gange er det ø der blive vist andre gange et ruder tegn med ? i, og det er i samme php fil det sker.
    har i en idé?
    koder i Query, jQtouch
    og UTF8

  20. By Niels on feb 4, 2011

    Tegnsætsproblemer er utaknemmelige og vanskelige at løse. Et sted at starte er f.eks. at undersøge at ALLE led er UTF-8 kodede på den rigtige måde… hvad det så end betyder.

    Ellers er mit bedste råd bare at forsøge dig frem med alle de mulige løsningsforslag du nu kan komme på. Også selvom de måske i første omgang ikke virker logiske.

  21. By Michael Boesen on aug 8, 2011

    Gammel tråd, men håber den stadig er aktiv. Er der nogen som gider at tage et kig på http://www.boesenfoto.dk/gallery

    Det er en Coppermine Foto database, hvor æøå fucker op når jeg eksportere fra Lightroom og uploader til Coppermine. Problemet var der ikke i LR 3.3, men efter update til 3.4.x virker det ikke mere. Adobe siger at LR nu er opdateret til at bruge korrekt meta/exif data og bruger UTF-8. Det siger Coppermine også. Jeg kan ikke dreje hvor fejlen er.

    Men jeg tænkte om nogen gad kigge på kode (Vis kilde) og måske lade mig vide om jeg kan add noget i Coppermine så det virker

    På forhånd tak

    Michael

Skriv en kommentar