Charset detection routine in PHP with Snoopy
Sometimes you can't leave everything being done automatically, like for instance the charset detection when you retrieve something from the web. With HTML and XML, those can be overidden inside the file, and this can be tricky (especially since you must give the correct encoding to the XML parser before giving to it the file). So, here is what I basically use in Radio.Blog to PLS. The depencies are Snoopy the HTTP client library, and a HTML Parser written by Jose Solorzano (unfortunately we don't have TagSoup in PHP). It's crude, but works... here we go:
function url_get_contents($url) {
$snoopy = new Snoopy;
$c_data = read_cache($url);
// [...]
if($snoopy->fetch($url)) {
$c_data['status'] = $snoopy->status;
$c_data['charset_embedded'] = false;
if($snoopy->status == 200) {
$c_data['charset'] = 'iso-8859-1';
foreach($snoopy->headers as $header) {
@list($key,$val) = preg_split('/[: ]+/', $header, 2);
$val = trim($val);
$key = strtolower($key);
switch($key) {
// [...]
case 'content-type':
$parts = preg_split('/[ ;=]+/', $key, 3);
$c_data['type'] = $parts[0];
if(isset($parts[1])) {
$c_data[$parts[1]] = $parts[2];
}
break;
}
}
$c_data['content'] = $snoopy->results;
$charset_found = false;
// is is raw XML? don't trust the Content-Type header
$off = strpos($c_data['content'], 'status != 304) {
if($snoopy->status >= 400 && $snoopy->status < 500) {
$c_data['error'] = true;
} else if($snoopy->status >= 500 && $snoopy->status < 600) {
$c_data['error'] = true;
}
// other error... what can we do?
}
} else {
// dooh
}
return $c_data;
}
function charsetFromHTML(&$c_data) {
// is it really HTML? We don't even know...
$subdoc = stristr($c_data['content'], '');
if($off2 === false) {
$off2 = strpos($subdoc, '');
}
if($off2 !== false) {
$parser = new HtmlParser(substr($subdoc, 0, $off2 + 7));
while ($parser->parse()) {
if($parser->iNodeType == NODE_TYPE_ELEMENT && strtolower($parser->iNodeName) == 'meta') {
if(isset($parser->iNodeAttributes['http-equiv'])) {
if(!strcasecmp($parser->iNodeAttributes['http-equiv'], 'content-type')) {
$parts = preg_split('/[ ;=]+/', $parser->iNodeAttributes['content'], 3);
$c_data['type'] = $parts[0];
if(isset($parts[1])) {
$c_data[$parts[1]] = $parts[2];
}
break;
}
}
} else if($parser->iNodeType == NODE_TYPE_ELEMENT && strtolower($parser->iNodeName) == 'body') {
break;
} else if($parser->iNodeType == NODE_TYPE_ENDELEMENT && strtolower($parser->iNodeName) == 'head') {
break;
}
}
}
}
}
(Cyberpunk, 2006/07/03 22:07) lien permanent
lundi 3 juillet 2006
On dit que la Grande Muraille est visible depuis l'espace. On dit aussi que la Chine est le nouvel Eldorado. Et on dit encore que les chinois vont tous nous bouffer. Et pourtant on sait pertinnement que les chinois ne sont pas anthropophages. Ils mangent des chats, d'accord, mais peut-on vraiment le leur reprocher ? Comme dirait un france-qui-tombeut primaire (oui, c'est une lapalissade) : ils ont compris, eux.


Je confirme, c'est grand et plat, et a part pour la circulation, moins stressant qu'à Shanghai... Par contre, 2008, c'est que dans deux ans, et je suis pas sur que ca soit suffisament clean pour satisfaire les milliers de portefeuilles sur pattes qui arriveront a ce moment là... Enfin bon... les chinois travaillent vite, ca sera peut etre tout a fait presentable en 2008...
Posté par Quentin, le mercredi 2 août 2006 à 09:11 #