кодировки. ispell+ php + win

Phoenix

есть некоторый скрипт, который должен принять строку, и выдать строку, где неправильно написаные слова типа "малоко" заменены на <span class="bad" id="w43214"> малоко </span>
вывод скрипта решено сделать в utf-8.
вызывающая страничка имеет кодировку win1251 и это не исправить.
вызов скрипта сделан черзе mootools аджаксом.
 
function getstr {

var strobj = document.getElementById('idstr');
var str = strobj.value;

//var myRequest = new Request({'url':'/spell/check.php',
// 'method': 'post',
// 'data': {'str': str}});

addstr({result:true, str:'request: ' + str});

var jsonRequest = new Request({url: "/spell/check.php?ac=pr",
method: 'post',
data: {'req': str},
onComplete: function(str){
alert(str);
var obj = eval('(' + str +')');
addstr(obj);
}
});

jsonRequest.send;
}

вопрос N1: правильно ли я понимаю, что данные отправятся в UTF8 в независимости от кодировки страницы?
орфография проверяется ispell.
К сожалению с виндой возникли трудности. просто написать
echo $str | ispell ...
не получается, видимо из-за различия кодировок.
решил сначала положить в файл, потом вызвать
type FILE | ispell
Опытным путём обнаружилось, что нужно в файл писать в win1251.
в файле вместо предполагаемого АБВГД вижу
 
d0 90 d0 91 d0 92 d0 93 d0 94

вопрос2: это utf8 ? редактор, после переключения в utf8 показывает АБВГД, но в доках пишут, что первые две цифры должны быть 04, а не d0.
далее.
функция, которая пишет в файл
 
function fillfile($filename,$str) {
//str in utf8.
global $debug;

$fh = fopen($filename,"w");
if(!$fh)
return FALSE;
ftruncate($fh,0);
$debug['prefill'][] = $str;

$str = iconv('UTF-8','windows-1251',$str);

$debug['fill'][] = $str;

fwrite($fh,$str);
fclose($fh);
return TRUE;

}


если закоментрировать iconv, то ничего не меняется. в файле будет utf.
вопрос3: iconv не работает? или что может не работать?
кстати, переменная $debug возвращается и показывается alert'ом(см. выше кусок джаваскрипта).
там AБВГД выглядит как
\u0410\u0411\u0412
более того, в $debug['prefill'] и $debug['fill'] содержится одна и таже строка.

conv3rsje

d0 90 d0 91 d0 92
это и есть утф-8
\u0410\u0411\u0412
это уникодное представление внутри языка
04 10 04 11 04 12
судя по всему в твоих "доках" упоминается кодировка utf-16be

Phoenix

всё. понял. \u перевёл как utf, а не уникод.
тогда вопрос такой: почему джаваскрипт не отображает русский текст?
судя по тому, что приходит в $debug['prefill'] (туда без всяких преобразований php должен положить строку, которая ему пришла в $_POST['str'])

то, что я посылаю, выводится как русский текст.
То, что приходит обратно - вот такими уникодами.
кстати, забыл написать, что ответ формируется так:
 
print json_encode(array('result'=>true,'str'=>$str,'badwords'=>$badwords,'debug'=>$debug;

kruzer25

К сожалению с виндой возникли трудности. просто написать
type $str | ispell ...
не получается, видимо из-за различия кодировок
Не из-за различия кодировок, а из-за того, что ты путаешь type и echo.
если закоментрировать iconv, то ничего не меняется. в файле будет utf.
вопрос3: iconv не работает? или что может не работать?
Лучше используй mbstring-функции.
global $debug;
За такое - сразу на расстрел.

Phoenix

Не из-за различия кодировок, а из-за того, что ты путаешь type и echo.

там echo использовалось. это я опечатался.
За такое - сразу на расстрел.

почему это?
кто ж виноват, что в пхп отладка никакая.

kruzer25

почему это?
Потому что тех, кто использует глобальные переменные, надо расстреливать.

Phoenix

mb_convert_encoding обрезало строку на букве A (английский буковки до неё сохранились.)
заменил
$str = iconv('UTF-8','windows-1251',$str);
на:
$str = mb_convert_encoding($str,'windows-1251','UTF-8');
есть подозрение, что в $str вообще непонятно что(что-то типа уникода пхпшного, хотя у пхп вроде нет уникода но пхп в ввиду своей интелектуальности пишет в файл в утф всё.

kruzer25

mb_convert_encoding обрезало строку на букве A (английский буковки до неё сохранились.)
Значит, ты неправильно указал кодировку, из которой происходит преобразование.
$str = mb_convert_encoding($str,'windows-1251','UTF-8');
Дай-ка binhex($str) до mb_convert_encoding

Phoenix

отличная мысль!
тестируемая строка:
dog
АБВГДабвгд
тест тест тест
тест тес тест
тезт тест тест

"prefill":["dog \u0410\u0411\u0412\u0413\u0414\u0430\u0431\u0432\u0433\u0434
\u0442\u0435\u0441\u0442 \u0442\u0435\u0441\u0442 \u0442\u0435\u0441\u0442
\u0442\u0435\u0441\u0442 \u0442\u0435\u0441 \u0442\u0435\u0441\u0442
\u0442\u0435\u0437\u0442 \u0442\u0435\u0441\u0442 \u0442\u0435\u0441\u0442"],
"prefillHEX":["646f67 20 d090 d091 d092 d093 d094 d0b0 d0b1 d0b2 d0b3 d0b4 20 d182 d0b5 d181 d182 20
d182 d0b5 d181 d18220d182d0b5d181d18220d182d0b5d181d18220
d182 d0b5 d18120d182d0b5d181d18220d182d0b5d0b7d18220
d182d0b5d181d18220d182d0b5d181d182"],
"fill":["dog "]

 
$debug['prefill'][] = $str;

$debug['prefillHEX'][] = bin2hex($str);

//$str = iconv('UTF-8','windows-1251//IGNORE',$str);
// $str = iconv('UTF-8','windows-1251',$str);

//$str = mb_convert_encoding($str,'windows-1251','UTF-8');
//$str = mb_convert_encoding($str,'windows-1251','auto');
$str = mb_convert_encoding($str,'windows-1251','UTF-8');

$debug['fill'][] = $str;

fwrite($fh,$str);
fclose($fh);

ошибок никаких не появляется..
может нужно подгрузить какие-нибудь таблицы для mbstring|iconv ?

kruzer25

Теперь попробуй просто создать скрипт вроде
<?php

$sHex = '646f6720d090d091d092d093d094d0b0d0b1d0b2d0b3d0b42
0d182d0b5d181d18220d182d0b5d181d18220d182d0b5d181d18220d182d0b5d181d18220d182d0b5d18120d182d0b5d181d18220d182d0b5d0b7d1822
0d182d0b5d181d18220d182d0b5d181d182';
$sRaw = hex2bin($sHex);
var_dump($sRaw);
$sConverted = mb_convert_encoding($sRaw, 'Windows-1251', 'UTF-8');
var_dump($sConverted);
?>

Варианты, откуда это лезет - что эта строка всё-таки не является корректной utf-8 строкой с кириллицей (под рукой сейчас ничего нет, чтобы проверить) или что php-то всё конвертирует правильно, просто тот, кому идёт строка в cp1251, ожидает utf-8 или что-то вроде того, и уже именно он валится на не-ascii байтах.
может нужно подгрузить какие-нибудь таблицы для mbstring|iconv ?
Для mbstring - нет.

Phoenix

результаты тестов:
вроде всё гуд.
string(206) "646f6720d090d091d092d093d0..."
string(103) "dog АБВГДабвгд тест тест тест тест тес тест тезт тест тест"
string(58) "dog АБВГДабвгд тест тест тест тест тес тест тезт тест тест"

первоя строка это utf
вторая win1251.

Phoenix

и уже именно он валится на не-ascii байтах.
ну так должен же что-нибудь в логах быть.
и почему тогда если он валится, если вся строка, но не в нужной кодеровке.

kruzer25

ну так должен же что-нибудь в логах быть.
В чьих логах? Как мы сейчас выяснили, с php у тебя всё в полном порядке.
и почему тогда если он валится, если вся строка, но не в нужной кодеровке.
Если нечто ожидает utf-8, а ему подсовывают cp1251, вполне возможен следующий вариант действий - идём по символам, обработали первый байт и дописали к выходным данным (т.к. первый бит этого байта - 0, и, значит, этот байт и есть символ обработали второй и дописали, обработали третий и дописали... обработали десятый байт - это должен быть первый байт трёхбайтного символа, обработали одиннадцатый байт - а он выглядит не как второй байт трёхбайтного символа, прекращаем обработку.

Phoenix

это я понимаю, но в данном случае мы кодируем utf-8 в win.
проблем быть не может ,кроме кракозябль. А получаем вполне читаемый текст в utf8

kruzer25

это я понимаю, но в данном случае мы кодируем utf-8 в win.
проблем быть не может ,кроме кракозябль. А получаем вполне читаемый текст в utf8
А теперь внятно объясни - что именно ты делаешь (по пунктам какой результат ожидаешь получить на каждом из этих пунктов и в конце, какой результат вместо этого получаешь в конце, какие результаты у тебя получаются посередине (там, где у тебя отладка какая-то есть).
Потому что уже ничего не понять - что там у тебя происходит, где происходит что-то не то...

Phoenix

подстава.
пока тут обсуждали. прога заработала.
по крайней мере в файле теперь win1251. (до: в utf-8 писала в файл.)
спасибо
Оставить комментарий
Имя или ник:
Комментарий: