Zjištění kódování webové stránky
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.
Diskuse
Gioel:
a kde sa to da najlepsie vyuzit?
27.5.2005 05:21:50
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)
27.5.2005 09:12:56
Gioel:
ale ved keby som aj zistil potrebne kodovanie a upravim na pozadovane tak tam budu take chyby, nie?
27.5.2005 09:49:02
Jaké chyby máš na mysli?
27.5.2005 10:04:42
Gioel:
Ako ze sa zobrazi zle ako ze niekto znaky sa zle zobrazia, to sa stane ked sa zmeni kodovanie, nie?
27.5.2005 12:21:16
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.
27.5.2005 14:15:36
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ěď.
31.12.2006 18:26:49
Š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.
6.3.2009 05:49:51
Díky za upozornění, změnilo se to v PHP 5.1. Opravil jsem to.
6.3.2009 06:04:38
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;
}
}
}
2.1.2010 17:15:56