Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > кодировка. сервер-сервер


Автор: bars80080 21.8.2008, 17:32
что-то я в шоке, а найти проблему не могу

посылаю запрос на rss-ленту, получаю xml-файл и парсю его (http://www.100dorog.ru/news/rss/rss.aspx)

происходит следующее, на локале у меня всё отрабатывает хорошо, перекладываю на один сервер, тоже хорошо, кладу на другой - вместо кирилицы знаки вопроса

сбрасывается она в utf-8, я её затем перекодирую на cp-1251 для занесения в БД и последующего отображения,

НО даже если не перекодировать, а чисто по приёме echo fread() открытого адреса ленты через fopen, всё равно знаки вопроса. и только на одном сервере.

чем и как это можно объяснить, а главное как бороться?

Добавлено через 57 секунд
да, чуть не забыл. другие ленты нормально обрабатываются на том серевере, к примеру с gismeteo

Добавлено через 12 минут и 14 секунд
php на локале 5.2.6, на работающем сервере 5.1.6, на сервере который буянит 4.4.8

Автор: Mal Hack 21.8.2008, 18:37
PHP на уровне языка стал поддерживать UTF только с 5 версии. Так что глюк на 4 очевиден.
Смена кодировок в браузере не помогает?
Если нет, надо код смотреть, возможно есть в нем явная ошибка.

Автор: Anarki 21.8.2008, 19:23
А лента в какой кодировке, кодировка страницы которая выводится и ленты, которая выводится в этой странице должны совпадать.

Автор: bars80080 21.8.2008, 19:54
Цитата(Mal Hack @  21.8.2008,  18:37 Найти цитируемый пост)
Смена кодировок в браузере не помогает?

нет, для работающего сервера и локального, если перекодировать iconv() поступающий текст, то выводит кирилицу как надо в cp1251. если не перекодировать, а сразу отправлять echo приходящие данные в браузер, то получаются кракозябры (разные знаки), выбираем в браузере кодировку utf-8 и текст превращается в нормальные слова кирилице

для не работающего сервера, как не выводи, вся кирилица всегда отображается знаками вопроса ????? ?????? ???. также записывается в БД и также записывается в файл


Цитата(Mal Hack @  21.8.2008,  18:37 Найти цитируемый пост)
надо код смотреть, возможно есть в нем явная ошибка. 

да вроде уже не на одной ленте опробовал


Цитата(Anarki @  21.8.2008,  19:23 Найти цитируемый пост)
А лента в какой кодировке, кодировка страницы которая выводится и ленты, которая выводится в этой странице должны совпадать

лента в utf-8. в первом посту её адрес. с работы уходил пытался с помощью get_headers() прочитать заголовки, да что-то наверно не так задавал, она мне вообще ничего не возвращала.

Автор: Mal Hack 21.8.2008, 20:07
bars80080, надо смотреть, как транспорт (получение) ленты или ее создание работают...
Так очевидно, древность PHP, вопрос в том, можно ли легко адаптировать под 4 код или нет.
Код может быть и правильный и рабочий, но для 4 ПХП упущена какая-то особенность, в результате чего - косяк.

Автор: bars80080 21.8.2008, 20:25
вот, нарыл у себя в домашних условиях эти куски
Код

function contentTag($parser, $data) {          //обработка содержимого в тэгах
    global $xmlg, $xmlw, $xmlt, $xmlc, $xmlf;
    ksort($xmlw); $a = trim($data);
    if(!empty($xmlc)) { $data = iconv($xmlc[0], $xmlc[1], $data); }
    if(!empty($xmlf)) { $data = xml_function($data); }
    if(!empty($a)) {
        for($i = 0; $i < count($xmlw); $i++) {
            if($i == 0) $t = &$xmlt[$xmlw[$i]]; else $t = &$t[$xmlw[$i]]; }
        if(isset($t[1])) $t[1] .= $data; else $t[1] = $data; /*dump($xmlw); echo ' = '.$t[1].'<br />';*/ }}
function xmlpar($addres) {
    global $xmlt;
    $xmlParser = xml_parser_create();
    $caseFold = xml_parser_get_option($xmlParser, XML_OPTION_CASE_FOLDING);
    $targetEncoding = xml_parser_get_option($xmlParser, XML_OPTION_TARGET_ENCODING);
    if($caseFold == 1) {
        xml_parser_set_option($xmlParser, XML_OPTION_CASE_FOLDING, false); }
    xml_set_element_handler($xmlParser, 'openTag', 'closeTag');
    xml_set_character_data_handler($xmlParser, 'contentTag');
    if(!($fp = @fopen($addres, 'r'))) { echo 'cannot open xml respond'; $r1['s'][0][0] = ''; return $r1; }
    while($data = fread($fp, 4096)) {
        if(!xml_parse($xmlParser, $data, feof($fp))) {
            die(sprintf("XML error: %s at line %d",xml_error_string(xml_get_error_code($xmlParser)),xml_get_current_line_number($xmlParser)));
            xml_parser_free($xmlParser); }}                     
    xml_parser_free($xmlParser);
    return $xmlt; } 
xmlpar принимает ленту, а contentTag обрабатывает, запихивая её в массив
скрипт нормально работает с несколькими лентами, в том числе и с utf-8
эта строчка if(!empty($xmlc)) { $data = iconv($xmlc[0], $xmlc[1], $data); } отвечает за перекодирование, но я её отключаю и ничего не меняется

Добавлено через 5 минут и 42 секунды
сейчас посмотрел. на этом же сервере этим скриптом парсятся ещё ленты http://informer.gismeteo.ru/xml/11034_1.xml и http://www.cbr.ru/scripts/XML_daily.asp?date_req= , но первая не содержит кирилицы, а вторая идёт в cp1251

Автор: bars80080 22.8.2008, 12:08
таки списываем эти глюки на сервер?

вот так и растут заплатки. теперь у меня эту ленту читает только сервер1, перекодирует, обрабатывает данные, заносит в БД.
сервер2 обращается к сервер1 и получает ленту уже в кодировке вин-1251. так работает

Автор: Mal Hack 22.8.2008, 12:27
bars80080, я с xml не работал на PHP, но скорее всего фишка в том, что 5 поддерживает использование UTF функциями trim и xml_*, а 4 - нет. Отсюда и косяк. Причина - банальна - отсутствие правильной работы с мультибайтовыми строками...

Это не глюк, это просто особенность старой ветки.

Автор: bars80080 22.8.2008, 12:43
да, ты прав. поставил вывод сразу после fread() и он отобразил текст в utf-8 как надо

скорее всего рубит trim, я заключил вывод в trim и текст исчез полностью, но что не так уже не стал разбираться, пусть так работает


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)