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?

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;
                        }
                    }
                }

Diskuse je zrušena z důvodu spamu.

avatar © 2005-2024 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.