Zjištění kódování webové stránky

Školení, která pořádám

Webová stránka může mít nastaveno kódování buď v HTTP hlavičce nebo v <meta> značce. Pokud toto kódování chceme zjistit PHP skriptem, lze postupovat takto:

<?php
/** Zjištění kódování HTML stránky z HTTP hlaviček nebo <meta> značky
* @param string cesta k lokálnímu nebo vzdálenému souboru
* @return string zjištěné kódování, false v případě nenalezení
* @copyright Jakub Vrána, https://php.vrana.cz/
*/
function get_charset($filename) {
    $fp = fopen($filename, "r");
    // zjištění z HTTP hlaviček
    $meta_data = stream_get_meta_data($fp);
    if (strtoupper($meta_data["wrapper_type"]) == "HTTP") {
        foreach ($meta_data["wrapper_data"] as $header) {
            if (stristr($header, "Content-Type:")) {
                if (preg_match('~; *charset=([^;]+)~i', $header, $match)) {
                    return $match[1];
                }
                break;
            }
        }
    }
    // zjištění z <meta> značky
    while (($s = fread($fp, 1024))) {
        if (preg_match('~<meta(\\s[^>]*http-equiv=[\'"]?Content-Type[^>]*)~i', $s, $matches)) {
            if (preg_match('~\\scontent=[\'"][^\'"]*; *charset=([^;\'"]+)~i', $matches[1], $match)) {
                return $match[1];
            }
            break;
        } elseif (stristr($s, "</head>")) { // stripos není použit proto, že je až v PHP 5
            break;
        }
    }
    return false;
}
echo get_charset("http://www.example.org/");
?>

Pokud je kódování nastaveno v HTTP hlavičce, zjistíme ho jednoduše díky funkci stream_get_meta_data. V opačném případě se ze souboru načítá kód do té doby, dokud se na značku s kódováním nenarazí nebo dokud neskončí HTML hlavičky. Pokud bychom se souborem potřebovali dále pracovat, bylo by samozřejmě lepší ho rovnou načíst (nejspíš funkcí stream_get_contents) a značku hledat až v načteném souboru. Přestože byla funkce primárně napsaná pro soubory dostupné protokolem HTTP, funguje i s místními soubory, kdy kódování zjišťuje pouze z <meta> značky. Pro načtení meta značky by se dala použít funkce get_meta_tags.

Jakub Vrána, Řešení problému, 27.5.2005, diskuse: 11 (nové: 0)

Diskuse

Gioel:

a kde sa to da najlepsie vyuzit?

Llaik:

Mimochodem, jake kodovani posilas v pozadavku na server (accept-charset)? Ono pak muzes dojit k tomu, ze tak funkce je v praxi docela nepouzitelna...

2Gioel: pokud z tech stranek sosas kusy textu, tak potrebujes zjistit, zda je mas prekodovavat do sveho a pripadne tedy z jakeho. Tj. vyuziti to mit muze. Jen to muze mit problemy u stranek, ktere se posilaji v tom kodovani, ktere si vyzadal klient (typicky mod_czech)

Gioel:

ale ved keby som aj zistil potrebne kodovanie a upravim na pozadovane tak tam budu take chyby, nie?

ikona Jakub Vrána OpenID:

Jaké chyby máš na mysli?

Gioel:

Ako ze sa zobrazi zle ako ze niekto znaky sa zle zobrazia, to sa stane ked sa zmeni kodovanie, nie?

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL: Reakce na: Gioel

Mordae:

Ne, to se stane pokud pošleš text v jiném kódování, než specifikuješ...
Právě kvůli těmto problémům je tu tahle fce - když chceš něco odjinud a přek=odovat to do kódování tvého webu. Zjednodušeně řečeno.

Markétka:

Ahoj. Chtěla bych se zeptat, jak docílim toho, aby se mé stránky zobrazovali v prohlížečích stejně. Např. na mozile to mám přesně podle mých představ, ale na internet explorer je to rozhozené. Obrázek je mimo a dokonce místo např. ž se zobrazí kostička. Taky bych se chtěla zeptat, jestli mi můžete doporučit nějakej program na tvorbu webových stránek. Mockrát děkuji za odpověď.

ikona Jakub Vrána OpenID:

Obrať se na nějaké diskusní fórum, třeba http://diskuse.jakpsatweb.cz/index.php?act…&forum=5.

Šroubek:

Dobrý skriptík - hodně mi pomohl...
Ale přece bych měl jednu připomnku: Podmínku 'if ($meta_data["wrapper_type"] == "HTTP")' bych roršířil o "http" (malými písmeny) - jinak v případě že testovaná stránka má hodnotu wrapper_type malým písmem tak tato podmínka neprojde a funkce vrátí hodnotu false.

ikona Jakub Vrána OpenID:

Díky za upozornění, změnilo se to v PHP 5.1. Opravil jsem to.

Radim Daniel Pánek:

Používám:
@$meta_data = stream_get_meta_data( $fp );

                if ( strtoupper ( $meta_data["wrapper_type"] ) == "HTTP" ) {

                    foreach ( $meta_data["wrapper_data"] as $header ) {

                        if ( stristr( $header, "Content-Type:" ) ) {

                            if ( preg_match('~; *charset=([^;]+)~i', $header, $match) ) {

                                return $match[1];

                            }

                            break;
                        }
                    }
                }
avatar © 2005-2020 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.