Определить в какой кодировке, сервер отдает документ.

FryDay

Новичок
Определить в какой кодировке, сервер отдает документ.

вообщем, пытаюсь парсить rss. возникла проблемка с определением кодировки отдаваемого сервером потока, оно понятно что как правило вверху есть пометка о кодировке(это я уже опредалил). Мне нужно полученные данные хранить в базе в utf-8 кодировке. Вообщем у меня это все организованно следующим оброзом 1. читает урл, определяет кодировку. 2. при помощи iconv конвертит из определенной в utf-8. но сдесь проблема, не хочет он нормально перекодировать. Следовательно мне представляется это тем что выставленная кодировка и кодировка отдаваемая сервером различны. Как мне б определить реальную отдаваемую кодировку.
 

SiMM

Новичок
> но сдесь проблема, не хочет он нормально перекодировать.
http://phpfaq.ru/debug
Телепаты в отпуске.

> Как мне б определить реальную отдаваемую кодировку.
Из соответствующих заголовков.
 

FryDay

Новичок
Автор оригинала: SiMM
> но сдесь проблема, не хочет он нормально перекодировать.
http://phpfaq.ru/debug
Телепаты в отпуске.

> Как мне б определить реальную отдаваемую кодировку.
Из соответствующих заголовков.
заявленная кодировка ведь может отличаться от отдаваемой или я ошибаюсь,что если она выставлена неправельно. У меня после перекодировки вылазит такая лажа
Àíåêäîòû
Àíîíñ àâãóñòîâñêîãî æóðíàëà Âåñòíèê Öâåòîâîäà
Áîíóñíûå ôèðìû Ëóæêà
Íîâîñòè ìèðà ëóêîâè÷íûõ
Êòî åùå íå çíàåò ïðî áóçóëüíèê?
Íå áîéòåñü ðåçàòü
Íåîáû÷íûå äåðåâüÿ
çÏÔÏ×ÉÍ Ë ÛËÏÌÅ ... ÒÏÄÉÔÅÌÅÊ
íÕÚÙËÁ ÕÞÅÂÅ ÐÏÍÅÈÁ
ðÒÏÛÕ ÓÌÏ×Á!
ëÁË ÎÁÕÞÉÔØ ÓÁÍÏÓÔÏÑÔÅÌØÎÏÓÔÉ
îÙÔØÅ - ×ÒÏÖÄÅÎÎÏÅ ÉÌÉ ÐÒÉÏÂÒÅÔÅÎÎÏÅ?
þÔÏÂÙ ÄÅÔÉ ÖÉÌÉ ÄÒÕÖÎÏ
îÅ ÄÅÌÁÊÔÅ ÉÚ ÍÁÌÙÛÁ éÈÔÉÁÎÄÒÁ!
PHP:
function getrss($url,&$items) {
global $channel;
global $use_cache,$cache_folder,$cache_valid;

if($use_cache) {
	$cache_filename=$cache_folder."/".md5($url).".rss";
	if(file_exists($cache_filename)) {
		$t=filemtime($cache_filename);
		$cache_create=((!$t)||($t<strtotime("now")-60*$cache_valid)); }
	else
		$cache_create=true;
	
	if($cache_create) {
		//cache not valid - create it again
		$simple = file($url);
		$f=fopen($cache_filename,"w");
		for($i=0;$i<count($simple);$i++)
			fwrite($f,$simple[$i]);
		fclose($f);
		$simple=implode('',$simple);
		}
	else
		$simple = implode('',file($cache_filename));
}
else
	$simple = implode('',file($url));



// определение кодировки фида
$encoding = array(
"MacArabic"         => "Arabic (Macintosh)",
"CP1256"            => "Arabic (Windows)",
"ISO-8859-2"        => "Central European (ISO-8859-2)",
"MacCentralEurope"  => "Central European (MacCE)",
"CP1250"            => "Central European (Windows1250)",
"ISO-8859-5"        => "Cyrillic (ISO-8859-5)",
"KOI8-R"            => "Cyrillic (KOI8-R)",
"KOI8-U"            => "Cyrillic (KOI8-U)",
"MacCyrillic"       => "Cyrillic (MacCyrillic)",
"CP1251"            => "Cyrillic (Windows1251)",
"Windows-1251"      => "Cyrillic (Windows1251)",
"ISO-8859-7"        => "Greek (ISO-8859-7)",
"MacGreek"          => "Greek (MacGreek)",
"CP1253"            => "Greek (Windows1253)",
"CP1255"            => "Hebrew (Windows)",
"MacHebrew"         => "Hebrew (Macintosh)",
"EUC-KR"            => "Korean (EUC-KR)",
"SHIFT_JIS"         => "Japanese (Shift_JIS)",
"EUC-JP"            => "Japanese (EUC)",
"ISO-2022-JP"       => "Japanese (JIS)",
"HZ"                => "Simplified Chinese (HZ)",
"GB2312"            => "Simplified Chinese (gb2312)",
"BIG5"              => "Traditional Chinese (big5)",
"MacThai"           => "Thai (Macintosh)",
"CP874"             => "Thai (Windows)",
"ISO-8859-5"        => "Turkish (Latin5)",
"MacTurkish"        => "Turkish (Macintosh)",
"CP1254"            => "Turkish (Windows)",
"UTF-8"             => "UTF-8",
"ISO-8859-1"        => "Western (Latin1)",
"Macintosh"         => "Western (Macintosh)",
"CP1252"            => "Western (Windows 1252)"
);

    foreach ($encoding as $valenc => $item) {
if (preg_match("/$valenc/i", $simple)) echo "<a href='".$url."'>".$item." OK</a> "; 
    }

$p = xml_parser_create();
xml_parse_into_struct($p,$simple,$vals,$index);
xml_parser_free($p);
$type=0;
$tmp[]=array("","","");
$id=0;
for($i=0;$i<count($vals);$i++) {

        $vals[$i]['value']=iconv($valenc,'UTF-8',$vals[$i]['value']);   


	if(($vals[$i]['tag']=="CHANNEL")&&($vals[$i]['type']=="open")) $id=$vals[$i]['level']+1;
	if(($type==0)&&($id==$vals[$i]['level']))
		switch($vals[$i]['tag']) {
		case "TITLE": $channel[0]=$vals[$i]['value']; break;
		case "LINK": $channel[1]=$vals[$i]['value']; break;
		case "DESCRIPTION": $channel[2]=$vals[$i]['value']; break;
		case "COPYRIGHT":
		case "DC:RIGHTS": $channel[3]=$vals[$i]['value']; break;
		case "MANAGINGEDITOR":
		case "DC:PUBLISHER": $channel[4]=$vals[$i]['value']; break;
		case "PUBDATE":
		case "DC:DATE": $channel[5]=$vals[$i]['value']; break;
		}

	else switch($vals[$i]['tag']) {
		case "TITLE": $tmp[0]=$vals[$i]['value']; break;
		case "LINK": $tmp[1]=$vals[$i]['value']; break;
		case "DESCRIPTION": $tmp[2]=$vals[$i]['value']; break;
		}

	if($vals[$i]['tag']=="ITEM") {
		if(($vals[$i]['type']=="open")&&($type==0)) $type=1;
		if($vals[$i]['type']=="close") {
			$items[]=$tmp;
			$tmp[0]="";
			$tmp[1]="";
			$tmp[2]="";
		}
	}

}

//print_r($channel);
//print_r($items);
} // end function getrss
-~{}~ 15.09.06 17:36:

вопрос решен всем спасибо. грабли были при определении кодировки фида. но вопрос о различии отдаваемой кодировки и определенной для меня открыт(так ради интереса). приведу код если кому понадобится пользуйте..
Код:
function getrss($url,&$items) {
global $channel;
global $use_cache,$cache_folder,$cache_valid;

if($use_cache) {
	$cache_filename=$cache_folder."/".md5($url).".rss";
	if(file_exists($cache_filename)) {
		$t=filemtime($cache_filename);
		$cache_create=((!$t)||($t<strtotime("now")-60*$cache_valid)); }
	else
		$cache_create=true;
	
	if($cache_create) {
		//cache not valid - create it again
		$simple = file($url);
		$f=fopen($cache_filename,"w");
		for($i=0;$i<count($simple);$i++)
			fwrite($f,$simple[$i]);
		fclose($f);
		$simple=implode('',$simple);
		}
	else
		$simple = implode('',file($cache_filename));
}
else
	$simple = implode('',file($url));



// определение кодировки фида
$encoding = array(
"MacArabic"         => "Arabic (Macintosh)",
"CP1256"            => "Arabic (Windows)",
"ISO-8859-2"        => "Central European (ISO-8859-2)",
"MacCentralEurope"  => "Central European (MacCE)",
"CP1250"            => "Central European (Windows1250)",
"ISO-8859-5"        => "Cyrillic (ISO-8859-5)",
"KOI8-R"            => "Cyrillic (KOI8-R)",
"KOI8-U"            => "Cyrillic (KOI8-U)",
"MacCyrillic"       => "Cyrillic (MacCyrillic)",
"CP1251"            => "Cyrillic (Windows1251)",
"Windows-1251"      => "Cyrillic (Windows1251)",
"ISO-8859-7"        => "Greek (ISO-8859-7)",
"MacGreek"          => "Greek (MacGreek)",
"CP1253"            => "Greek (Windows1253)",
"CP1255"            => "Hebrew (Windows)",
"MacHebrew"         => "Hebrew (Macintosh)",
"EUC-KR"            => "Korean (EUC-KR)",
"SHIFT_JIS"         => "Japanese (Shift_JIS)",
"EUC-JP"            => "Japanese (EUC)",
"ISO-2022-JP"       => "Japanese (JIS)",
"HZ"                => "Simplified Chinese (HZ)",
"GB2312"            => "Simplified Chinese (gb2312)",
"BIG5"              => "Traditional Chinese (big5)",
"MacThai"           => "Thai (Macintosh)",
"CP874"             => "Thai (Windows)",
"ISO-8859-5"        => "Turkish (Latin5)",
"MacTurkish"        => "Turkish (Macintosh)",
"CP1254"            => "Turkish (Windows)",
"UTF-8"             => "UTF-8",
"ISO-8859-1"        => "Western (Latin1)",
"Macintosh"         => "Western (Macintosh)",
"CP1252"            => "Western (Windows 1252)"
);

    foreach ($encoding as $valenc => $item) {
if (preg_match("/$valenc/i", $simple)) $enc=$valenc;
    }

echo "<a href='".$url."'>".$enc." OK</a> ";

$p = xml_parser_create();
xml_parse_into_struct($p,$simple,$vals,$index);
xml_parser_free($p);
$type=0;
$tmp[]=array("","","");
$id=0;
for($i=0;$i<count($vals);$i++) {

         $vals[$i]['value']=convert_to_utf($enc, $vals[$i]['value']);

	if(($vals[$i]['tag']=="CHANNEL")&&($vals[$i]['type']=="open")) $id=$vals[$i]['level']+1;
	if(($type==0)&&($id==$vals[$i]['level']))
		switch($vals[$i]['tag']) {
		case "TITLE": $channel[0]=$vals[$i]['value']; break;
		case "LINK": $channel[1]=$vals[$i]['value']; break;
		case "DESCRIPTION": $channel[2]=$vals[$i]['value']; break;
		case "COPYRIGHT":
		case "DC:RIGHTS": $channel[3]=$vals[$i]['value']; break;
		case "MANAGINGEDITOR":
		case "DC:PUBLISHER": $channel[4]=$vals[$i]['value']; break;
		case "PUBDATE":
		case "DC:DATE": $channel[5]=$vals[$i]['value']; break;
		}

	else switch($vals[$i]['tag']) {
		case "TITLE": $tmp[0]=$vals[$i]['value']; break;
		case "LINK": $tmp[1]=$vals[$i]['value']; break;
		case "DESCRIPTION": $tmp[2]=$vals[$i]['value']; break;
		}

	if($vals[$i]['tag']=="ITEM") {
		if(($vals[$i]['type']=="open")&&($type==0)) $type=1;
		if($vals[$i]['type']=="close") {
			$items[]=$tmp;
			$tmp[0]="";
			$tmp[1]="";
			$tmp[2]="";
		}
	}

}

//print_r($channel);
//print_r($items);
} // end function getrss

function convert_to_utf($encoding, $data)
{
  if (function_exists('iconv')) {
    $out = iconv($encoding, 'utf-8', $data);
  }
  else if (function_exists('mb_convert_encoding')) {
    $out = mb_convert_encoding($data, 'utf-8', $encoding);
  }
  else if (function_exists('recode_string')) {
    $out = recode_string($encoding .'..utf-8', $data);
  }
  else {
    watchdog('php', t("Unsupported encoding '%s'. Please install iconv, GNU recode or mbstring for PHP.", array('%s' => $encoding)), WATCHDOG_ERROR);
    return FALSE;
  } 
  return $out;
}
щас потестируем.
 

SiMM

Новичок
> но вопрос о различии отдаваемой кодировки и определенной для меня открыт
1. Телепаты в отпуске.
2. http://webhelp.ru
3. http://phpfaq.ru/debug

И хватит уже форум простынями заваливать.

-~{}~ 15.09.06 19:20:

[telepat mode]
В заголовке XML
Код:
<?xml version="1.0" encoding="Windows-1251"?>
кодировки может и не быть - она может указываться в хидере отклика от сервера.
[/telepat mode]
 

FryDay

Новичок
SiMM я про то и говорю что сервер может отдать в одной кодировке а encoding="БЫТЬ ДРУГИМ". или это не может быть причиной плохой конвертации кодировоки?

если этот заголокок стандартного типа то можно так выдерать '^<\?xml[^>]+encoding="([^"]+)"', я прав? ладно и так пока работает.

отклик ловить буду когда понадобится а щас и так отлично работает. (тока 'ш' при перекодировке из koi-r не показывается следовательно ее надо заменять до применения функции convert_to_utf)

всем спасибо кто участвовал в осебенности SiMM

p.s все вопросы реторические, т.к. нормальных ответов сдесь не услыхать. SiMM прости за простыни:D короче не могу пока.
 

SiMM

Новичок
> SiMM я про то и говорю что сервер может отдать в одной кодировке а encoding="БЫТЬ ДРУГИМ". или это не может быть причиной плохой конвертации кодировоки?
И? Во-первых, давно бы мог уже дать ссылку на такой RSS, во-вторых - если RSS не соответствует спецификации - это камень в огород её владельца - пущай разбирается и приводит в порядок.

> если этот заголокок стандартного типа то можно так выдерать '^<\?xml[^>]+encoding="([^"]+)"', я прав? ладно и так пока работает.
Он может быть не указан, а выдаваться хидером. В последнем случае при чтении файла из кэша хидера у тебя не будет, соответсвенно исходную кодировку ты в кэше не найдёшь. Хотя я это тоже отнёс бы к "криворукости" кодера.
 
Сверху