Gjest Slettet-rXRozPkg Skrevet 12. mars 2007 Del Skrevet 12. mars 2007 (endret) Etter å ha svart på en del tråder med ÆØÅ-problematikk og andre særskandinaviske tegn, så tenkte jeg det kunne vært en fordel å lage en tråd med generell informasjon om dette. Forslag, forbedringer og feilrettinger vil bli tatt med fortløpende. Here goes: Har du problemer med norske tegn, ÆØÅ, eller andre særskandinaviske tegn i ditt PHP-script eller din PHP-applikasjon? - Vises dine norske, eller skandinaviske tegn som spørsmålstegn eller firkanter istedenfor ÆØÅ, så er antagentligvis problemet at dine data er i iso-8859-1-format, mens nettleseren prøver å vise fram dataene i utf-8-format. - Vises dine norske, eller skandinaviske tegn som en kombinasjon av to tegn, f.eks ø istedenfor ø, så er antagentligvis problemet at dine data er i utf-8-format, mens nettleseren prøver å vise fram dataene i iso-8859-1-format. Hvorfor prøver så nettleseren å vise fram i "feil" tegnsett? 1. Har du angitt tegnsett i HTML-headeren? - Ja: Sjekk om siden virker skikkelig hvis du overstyrer tegnsettet nettleseren bruker. Dette kan gjøres i IE7, FireFox og Opera med letthet (klikk for større bilde): Internet Explorer 7: FireFox 1.5/2: Opera 9: Ser siden din pluttselig bra ut hvis du velger UTF-8 eller ISO-8859-1 manuelt her? Da kan du lese vidre under "Nei". Ser siden fortsatt rar ut, gå vidre til punkt 2. Hvis du ikke finner svaret der, skriv en post i denne tråden. - Nei / Vet ikke: Sjekk kildekoden til din nettside. Noe tilsvarende dette skal ligge inne i <head> tag'en: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> eller: <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> To eksempler på fulle headere i XHTML og HTML: Full header i XHTML 1.0 Transitional: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Jeg skal vise deg ÆØÅ jeg!</title> <link href="style.css" rel="stylesheet" type="text/css" media="all" /> </head> Full header i HTML 4.01: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> <title>Jeg skal vise deg ÆØÅ jeg!</title> <link href="style.css" rel="stylesheet" type="text/css"> </head> Har du fortsatt ikke funnet løsningen, les vidre på punkt 2: 2. Blander du statisk og dynamisk data? Hvis f.eks. siden din består av artikler som blir hentet ut fra en database, og en meny som er statisk, så er svaret her ja. Svarte du ja i punkt 1, så les hele punkt 2 for tips på hvordan du kan finne rett tegnsett for dine data. - Ja: Er du sikker på at begge kildene bruker samme tegnsett? Statiske data, som HTML lagret rett i en PHP-fil, eller f.eks. en include()/require() er ofte laget i en teksteditor. Når man lagrer filene, så er det også her viktig å tenke på tegnsett. Til og med Notepad lar deg velge tegnsett (ANSI og tre varianter av unicode, der UTF-8 er den mest brukbare). (include()/require() kan selvsagt også brukes til dynamiske data) Pass altså på å lagre statisk innhold i PHP-/tekstfiler med rett tegnsett i forhold til det som står nevnt i punkt 1. Støtter ikke din editor dette, så burde du seriøst vurdere å bytte. - Nei: Hvis svaret er nei, så er det meste av innholdet på siden hentet ut i fra en eller annen database. Igjen er det viktigste å finne ut av hva slags tegnsett er det faktisk dataene har. Bruker man MySQL 4.1 eller 5, så har man skikkelig støtte for tegnsett. Under viser jeg et eksempel på en MySQL-tabell, og hvordan man kan se hva slags tegnsett som blir brukt: mysql> SHOW FULL COLUMNS FROM table; +---------+---------------+----------------+------+-----+---------+----------------+---------------------------------+---------+ | Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment | +---------+---------------+----------------+------+-----+---------+----------------+---------------------------------+---------+ | id | int(11) | NULL | NO | PRI | NULL | auto_increment | select,insert,update,references | | | prefix | varchar(20) | utf8_danish_ci | NO | | | | select,insert,update,references | | | field | varchar(255) | utf8_danish_ci | NO | | | | select,insert,update,references | | +---------+---------------+----------------+------+-----+---------+----------------+---------------------------------+---------+ 'utf8_danish_ci' er brukt her, som dekker det som trengs av norske spesialtegn. Man kan også bruke 'utf8_general_ci', men det kan få konsekvenser for sortering etter alfabetisk rekkefølge. Tilsvarende for iso-8859-1 i MySQL-verdenen er 'latin1_danish_ci' Bruker du phpMyAdmin, så kan du enkelt lage nye databaser, og endre tegnsett. Klikk for større bilder. Ny database: Eksisterende tabell, man kan stille inn tegnsett per kolonne. Her er et eksempel på hvordan du kan lage en ny database, og sette rett tegnsett med kommandolinjeklienten: UTF-8: CREATE DATABASE dbnavn CHARACTER SET utf8 COLLATE utf8_danish_ci; ISO-8859-1: CREATE DATABASE dbnavn CHARACTER SET latin1 COLLATE latin1_danish_ci; (etter dette kommer tilganger/passord osv, men det har ikke noe med tegnsett å gjøre) Har du allerede en eksisterende database med data, kan du bruke mysqldump, opprette databasen på nytt som over, og legge til 'SET NAMES utf8' eller 'SET NAMES latin1' helt i toppen (første linje) av dumpen. Søk også igjennom, og se at SET NAMES ikke forekommer mer enn helt i toppen. Uansett om svaret er ja eller nei, så kan man alltids konvertere mellom to forskjellige tegnsett. Konvertering fra ISO-8859-1 til UTF-8 eller omvendt kan gjøres med PHP-funksjonene utf8_encode() og utf8_decode(). Hvis du har mbstring-utvidelsen installert (sjekk med phpinfo()), så kan en variant av denne funksjonen brukes til å konvertere fra et tegnsett til et annet: function convertCharacterEncoding($content) { // Convert encoding from charset X to utf8 if needed. $characterEncoding = mb_detect_encoding($content, 'UTF-8, UTF-16, ISO-8859-1, ISO-8859-15, Windows-1252, ASCII'); switch ($characterEncoding) { case "UTF-8": // Do nothing break; case "ISO-8859-1": $content = utf8_encode($content); break; default: $content = mb_convert_encoding($content,"UTF-8",$characterEncoding); break; } return $content; } Er du usikker på hvilket tegnsett dataene dine har, så kan du også bruke mbstring til å lage en funksjon som dette: function detectCharacterEncoding($string) { $characterEncoding = mb_detect_encoding($string, 'UTF-8, UTF-16, ISO-8859-1, ISO-8859-15, Windows-1252, ASCII'); return $characterEncoding; } I begge funksjonene over har jeg tatt med et utvalg av vanlige tegnsett. I noen tilfeller kan utf-8 bli returnert hvis PHP ikke finner ut av tegnsettet (det ligger ikke i listen). For å legge til flere tegnsett, er det bare å ta en kikk på listen her (Supported Character Encodings), og legge til i funksjonene. Har du ikke mbstring-utvidelsen, så kan det hende at iconv er tilgjengelig. Denne utvidelsen kan også konvertere mellom forskjellige tegnsett. En siste mulighet er å bruke selve databasen til å bytte mellom tegnsett. MySQL har muligheten til å sette tegnsettet data returneres med ved å bruke SET NAMES (nevnt tidligere) eller SET CHARACTER SET. Dette kan du lese mer om her. Ninjatriks: Kjør mysql_query("SET NAMES 'utf8'"); eller mysqli_query("SET NAMES 'utf8'" ); rett etter du har koblet deg til databasen. 3. Jeg genererer filer, som f.eks. .xml eller .pdf med PHP og sender dette direkte til nettleseren, og har problemer med tegnsett. Igjen så bør du finne ut av hva slags data det er du prøver å sende til nettleseren. Når du har funnet ut av dette, så må du angi det rette tegnsettet i headeren. Dette gjøres på en annen måte enn i HTML, ved bruk av header(). Eksempler: header("Content-Type: *mimetype*; charset=UTF-8"); eller header("Content-Type: *mimetype*; charset=ISO-8859-1"); *mimetype* skal selvsagt byttes ut med mimetypen du skal sende. Siden header() også kan brukes til å sette tegnsett på vanlige HTML/XHTML-dokumenter, må man passe på at man ikke lager en (mulig) konflikt med det som står i <head>-taggen i dokumentet! For å se hva slags HTTP-headere som sendes til og fra nettleseren, kan du bruke Live HTTP headers-utvidelsen til FireFox. Under er et screenshot av denne utvidelsen etter et besøk på en tilfeldig artikkel fra HW.no (klikk for større bilde): Jeg har markert to viktige ting med røde piler. Pil 1 viser hva slags tegnsett som nettleseren sier den søtter til webserveren. Pil 2 viser hva slags tegnsett som blir brukt på det som webserveren sender tilbake til nettleseren. Andre grunner til at dine data blir vist med feil tegnsett kan være: PHP: I konfigurasjonsfila til PHP (php.ini), kan man sette standard tegnsett og standard mimetype. Som standard er dette ikke tegnsett skrudd på, men hvis du sitter på en delt webhost, så kan det jo være at de som drifter serveren har gjort det. Det man skal se etter er default_charset = "iso-8859-1". Har du ikke tilgang til php.ini, så kan man også finne denne informasjonen ved hjelp av phpinfo(). Det kan hende at man kan bruke ini_set() til å overstyre verdien, alt ettersom hvordan PHP er konfigurert. Webserveren: I apache2 og apache 1.3, kan man også sette standard tegnsett. Se etter AddDefaultCharset UTF-8 (eller tilsvarende) i /etc/apache2/conf.d/charset og/eller httpd.conf (eller hvor nå enn du har lagt inn konfigurasjonsfilene). Står det AddDefaultCharset On tilsvarer dette iso-8859-1, alle andre verdier blir tolket som det faktiske tegnsettet du ønsker å bruke. Man fjerner enkelt standaardtegnsettet ved å slette linja, eller kommentere den ut med et #-tegn. Apache må så startes på nytt. Har du ikke tilgang til å konfigurere apache, så kan du bruke .htaccess til det samme. Bruker du IIS, kan du ta en kikk her. Annet: Hva er egentlig forskjellen på UTF-8, ISO-8859-x, ASCII og andre tegnsett? Litt teori bak praksisen over: *kommer snart* Oversikt over de vanligste tegnsettene, og hva de blir kalt i forskjellige sammenhenger: HTML/XHTML/XML : UTF-8 ISO-8859-1 US-ASCII WINDOWS-1252 PHP: UTF-8 ISO-8859-1 ASCII CP1252 MySQL: utf8 latin1 ascii latin1 PostgreSQL UTF8 LATIN1 SQL_ASCII WIN1252 Hovedpoenget for å finne ut av ÆØÅ-problemer er kort oppsummert: 1. Finn ut hva slags tegnsett dine data har. 2. Konverter dataene eller angi rett tegnsett i det som sendes til nettleseren. Har du muligheten til å velge, bruk UTF-8! Til slutt, lenker og informasjon du burde ta en titt på: Vanlige tegnsett du kommer til å støte på: ISO-8859-1 http://en.wikipedia.org/wiki/ISO/IEC_8859-1 ISO-8859-15 http://en.wikipedia.org/wiki/ISO/IEC_8859-15 UTF-8 http://en.wikipedia.org/wiki/UTF-8 Windows-1252 (CP1252) http://en.wikipedia.org/wiki/Windows-1252 ANSI http://en.wikipedia.org/wiki/Windows_code_page ASCII http://en.wikipedia.org/wiki/Ascii Kjekke lenker: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) Sorting it all out http://no.php.net/mbstring http://no.php.net/manual/en/function.utf8-encode.php http://no.php.net/manual/en/function.utf8-decode.php http://no.php.net/manual/en/function.mb-detect-encoding.php http://no.php.net/manual/en/function.mb-convert-encoding.php http://no.php.net/iconv/ http://en.wikipedia.org/wiki/Collation http://en.wikipedia.org/wiki/Character_sets http://en.wikipedia.org/wiki/Character_encoding http://en.wikipedia.org/wiki/Multipurpose_...Mail_Extensions http://dev.mysql.com/doc/refman/5.0/en/charset.html http://dev.mysql.com/doc/refman/5.0/en/charset-syntax.html http://dev.mysql.com/doc/refman/5.0/en/mysqldump.html http://www.utf-8.com/ http://www.iana.org/assignments/media-types/ (MIME-types) http://www.unicode.org/ Stikkord (for søkefunksjonen): Collation Collate Tegnsett Character encoding Character set Endret 10. februar 2009 av Slettet-rXRozPkg Lenke til kommentar
Gjest Slettet-rXRozPkg Skrevet 12. mars 2007 Del Skrevet 12. mars 2007 (endret) Oppdateringer: 10.02.2009: - La til et ninjatriks; mysql_query("SET NAMES 'utf8'") siden dette har blitt diskutert en del ganger siden siste oppdatering. 07.05.2007: - La til "Andre grunner til at dine data blir vist med feil tegnsett kan være", men informasjon om php.ini og /etc/apache2/conf.d/charset, sistnevnte etter tips fra marsipankake og -morten. 13.03.2007: - La til mer informasjon om header() og bruk av Live HTTP headers etter tips fra -morten. - La til kort oversikt over hva noen av de forskjellige tegnsettene blir kalt i HTML, PHP, MySQL og PostgreSQL. Endret 10. februar 2009 av Slettet-rXRozPkg Lenke til kommentar
-morten Skrevet 12. mars 2007 Del Skrevet 12. mars 2007 Veldig bra! Tenkte faktisk det samme i går kveld, og vurderte å skrive noe lignende. Men du kom meg i forkjøpet Andre ting du bør ha med: Litt mer om at HTTP-headeren også sender tegnsett, og at den kan endres både med .htaccess, httpd.conf og header(). Det bør også nevnes at HTTP-headeren og HTML-headeren godt kan si motsatt tegnsett, og da blir det krøll. For å se på HTTP-headeren kan man bruke denne extensionen til firefox: http://livehttpheaders.mozdev.org/ I tillegg kan det jo nevnes at alle nettleserene har et valg for å overstyre hvilket tegnsett siden skal tolkes som (Vis-> Koding i IE). Det kan jo være en kjapp måte å finne ut hva som blir riktig på. Lenke til kommentar
Runar0 Skrevet 12. mars 2007 Del Skrevet 12. mars 2007 Takker for denne posten, har hatt ein god del problemer med dette før. Veldig informativ og oversiktelig Lenke til kommentar
Gjest Slettet-rXRozPkg Skrevet 13. mars 2007 Del Skrevet 13. mars 2007 (endret) Da har jeg tatt med forslagene til -morten, og gjort noen andre mindre oppdateringer. Jeg fant forøvrig en typisk ÆØÅ-feil på HW.no nå nettopp: Endret 13. mars 2007 av Slettet-rXRozPkg Lenke til kommentar
Gjest Slettet+9871234 Skrevet 15. mars 2007 Del Skrevet 15. mars 2007 veldig bra og informativ tråd. digg at du lagde sånn throubleshooting av det!! Lenke til kommentar
marsipankake Skrevet 16. mars 2007 Del Skrevet 16. mars 2007 (endret) Jeg var en av de som spurte om hjelp. Her er hvordan jeg løste problemet. Bruker ubuntu linux. Har installert apache og php5 lokalt. Redigerte /etc/apache2/conf.d/charset Byttet ut UTF-8 med ISO-8859-1 Takk! Endret 16. mars 2007 av marsipankake Lenke til kommentar
Bakke Skrevet 16. mars 2007 Del Skrevet 16. mars 2007 (endret) Takker for denne tråden, fint at noen tar seg tid til å lage en slik hjelpe tråd Endret 16. mars 2007 av mhbakke Lenke til kommentar
Kimble Skrevet 16. mars 2007 Del Skrevet 16. mars 2007 Sinnsykt bra! Er det en ting som ofte gjør meg usikker så er det styret med tegnsett. Noen som vet hvordan dette påvirkes når php 6 en gang kommer med støtte for unicode? Lenke til kommentar
Kagee Skrevet 2. mai 2007 Del Skrevet 2. mai 2007 Jeg skjønner ikke hvorfor denne tråden ikke er sticky/annonsering - kan noen fikse på det? Lenke til kommentar
Crowly Skrevet 2. mai 2007 Del Skrevet 2. mai 2007 Vet ikke om dette er helt relevant for teamet, men å bruke htmlentities() for å konvertere f.eks å til å kan være kjekt. Hjelper ikke så mye på kildekoden, men på informasjonen som blir vist i nettleseren. Lenke til kommentar
???????? Skrevet 3. mai 2007 Del Skrevet 3. mai 2007 jeg må nesten si meg enig med crowly her... æøå er tegns som lager krøll, og om sjansen er til stede for at brukeren ikke alltid har en browser med vår iso så er også sjansen til stede for at det kan bli krøll... Utgangspunk, ikke bruk æøå, men html kodene å ... Merk at du er ikke befridd for problemer like vel! Hvis brukeren sender iso-x koder i f.eks. et søkefelt så gir dette problemer på utf lagring, så konverter her. Men, utganspunket burde være å hoppe over æøå. Lenke til kommentar
-morten Skrevet 6. mai 2007 Del Skrevet 6. mai 2007 Har du i det hele tatt lest den første posten? Det blir ikke krøll hvis du vet hva du holder på med. Og htmlentities kan lage krøll de også, feks hvis du skal lage en RSS-feed. Lenke til kommentar
Gjest Slettet-rXRozPkg Skrevet 7. mai 2007 Del Skrevet 7. mai 2007 Jeg kan vel legge til en "When all else fails"-seksjon, som beskriver litt bruk av htmlentitites. Lenke til kommentar
G2Petter Skrevet 7. mai 2007 Del Skrevet 7. mai 2007 En ting som jeg har hatt litt problemer med, er at enkelte editorer bruker UTF-8 med BOM, ("Byte Order Mark", om jeg ikke tar helt feil.) som gir deg en "Headers already sent"-feil. Før jeg fant ut av dette brukte jeg ISO i stedet, med de problemer det medførte. Lenke til kommentar
Bakke Skrevet 9. mai 2007 Del Skrevet 9. mai 2007 Hvorfor er ikke denne tråden blitt sticky/annonsering? Lenke til kommentar
Ståle Skrevet 9. mai 2007 Del Skrevet 9. mai 2007 (endret) Jeg lurer litt jeg ogsa. Plagsomt a matte soke etter den for a gi link til folk som spor. Endret 9. mai 2007 av Ståle Lenke til kommentar
Kagee Skrevet 9. mai 2007 Del Skrevet 9. mai 2007 Jeg anbefaler at det heller gjøres noe likt det som er planlagt på GN/Linux-forumet - en samletråd som bare inneholder linker til viktige, ofte refererte til tråder - en slags HOW-TO/WHY/WHEN Lenke til kommentar
Martin A. Skrevet 9. mai 2007 Del Skrevet 9. mai 2007 Jeg foreslår at '.' i emnetittelen byttes med '?'. Slik det er nå så oppfattet jeg dette som et spørsmål, og ikke en "how-to". Lenke til kommentar
Ståle Skrevet 19. mai 2007 Del Skrevet 19. mai 2007 Sporsmal; hvorfor ligger denne i PHP kategorien? (Burde ihvertfall vart i begge) og hvorfor er ikke den sticky enda? Les et av de nyeste innleggene i HTML delen. https://www.diskusjon.no/index.php?showtopic=767625&hl= Lenke til kommentar
Anbefalte innlegg
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 kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå