Бются данные при передаче кодировки UTF-16BE

nut

Новичок
Бются данные при передаче кодировки UTF-16BE

Необходимо принять сообшение в кодировке UTF-16BE. Проблема состоит в том, что после первого пробела сообщение обрывается. Я его декодирую так: iconv("UTF-16BE","windows-1251",$msg).
Если операцию перекодировки делаю в одном файле, перекодирует в любом направлении нормально.
 

SiMM

Новичок
Тестовый пример, где обрывается (значение $msg), в студию.
 

nut

Новичок
файл№1 (отправитель)
<form action="3.php" method="GET">
<TEXTAREA name="name" cols="30" rows="10">
<?
echo iconv("windows-1251","UTF-16BE",'тестовое сообщение пробелы проходят!!');
?></TEXTAREA>
<INPUT type="submit" value="ok">
</form>

файл№2 (приемник)
<?
echo iconv("UTF-16BE","windows-1251",$HTTP_GET_VARS['name']);
?>

ЛЮДИ ПОМОГИТЕ ЗАПАРИЛСЯ УЖЕ. гдн-то теряются байты, визуально строки одинаковы, а при декодировании-лажа.
 

SiMM

Новичок
nut, т.е. ты утверждаешь, что у тебя не выполняется правильно код
PHP:
$var=iconv('windows-1251','UTF-16BE','тестовое сообщение пробелы проходят!!');
echo iconv('UTF-16BE','windows-1251',$var);
? Если он выполняется, то грабли не в iconv - разбирайся с тем, что к тебе реально приходит GET-ом.
 

nut

Новичок
НЕТ!! этот код как раз и выполняется в том то и прикол, а вот пересылка не работает!

-~{}~ 13.10.04 13:41:

а может ли быть так, что апача не знает этой кодировки, я работаю под виндой! может ли это быть проблемой ОС?!
 

nut

Новичок
а как это посмотреть в байтах? если я просто в браузере просматриваю- они одинаковы, а если проверяю условием то разные.
Что если это и вправду не хватает кодировки апачам?
 

nut

Новичок
в общем я в полном замешательстве!!!
Я проделал подобную процедуру не через GET, а через файл, все передается.

Вопрос: какая разница, передаю я сообщение GETом в cp-1251 или UTF-16?
 

SiMM

Новичок
При передаче через GET у тебя всё идёт через клиента/апач, при передаче через файл ничего этого не происходит. var_dump, имхо, тут не очень удобен, удобнее что-то вроде
PHP:
for ($i=0;$i<strlen($name);$i++) echo str_pad(dechex(ord($name{$i})),2,0,STR_PAD_LEFT);
Получаем на первой странице:
0442043504410442043e0432043e043500200441043e043e043104490435043d043804350020043f0440043e04310435043b044b0020043f0440043e0445043e0434044f044200210021
0442043504410442043e0432043e043520200441043e043e043104490435043d043804352020043f0440043e04310435043b044b2020043f0440043e0445043e0434044f044220212021
на второй. Выводы сам сделаешь? :)
PS: и конечно же на первой стояло что-то вроде <META http-equiv="Content-Type" content="text/html; charset=UTF-16BE">
 

nut

Новичок
Извините но убог умом, не сделал вывод.

У меня такая задача: мне присылают сообщение, там откуда его присылают я ничего редактировать не могу, вместе с мессагой мне присылают ключ, мол это такая кодировка. Причем присылают GETом. Вопрос как мне корректно его принять!???
 

SiMM

Новичок
Да, что-то я местами ошибся, но код ты мог и сам подправить ;)
Вобщем (на моей машине) суть в том, что ASCII-символ 0 передаётся браузером как пробел, т.е.
PHP:
echo iconv("UTF-16BE","windows-1251",str_replace(' ',"\x0",$_GET['name']));
вполне работает (по крайней мере - у меня). Но никаких гарантий, что это будет работать как всегда, так и вообще, нет. Но куда и как копать - я тебе показал.
PS: что-то я не подумал сразу, но ещё удобнее будет
PHP:
for ($i=0;$i<strlen($name);$i++) echo str_pad(dechex(ord($name{$i})),2,0,STR_PAD_LEFT).'.';
;)
 

nut

Новичок
помоему дело в апаче и эту болезнь надо лечить добавлением кодировки, я уверен в этом на 99%.
 

SiMM

Новичок
Автор оригинала: nut
эту болезнь надо лечить добавлением кодировки, я уверен в этом на 99%.
У софта, написанного на C/C++ вообще несколько странное отношение к символу с кодом 0, поскольку встроенные стринги считают его признаком конца строки. Кстати, ни в одной из апачевских таблиц кодировки, лежащих под виндой в Apache/conf/tanles, такой символ даже не упоминается - поэтому, врядли стоит рассчитывать на лечение подобной настройкой. Кстати, мой первоначальный способ лечения несовсем верен - правильнее будет преобразовывать пару типа %20%XX в пару %00%XX (рассматривая при этом каждый знак как пару, поскольку кодировка - 16битная). На мой взгляд разумнее было бы воспользоваться UTF-7 или UTF-8 вместо Unicode. И ещё - на затравку - у кого-нибудь код
PHP:
if (!isset($_GET['var']))
  echo file_get_contents('http://'.$_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME'].'?var=%00');
else echo 'URL-кодированный символ с кодом %00 преобразовался в символ с кодом '.ord($_GET['var']{0});
запущенный в браузере без указания параметра var возвращает что-либо отличное от "URL-кодированный символ с кодом %00 преобразовался в символ с кодом 32"?
 

nut

Новичок
Дело в том, что не читается не только пробел, но и цифры, 1,2 и т.п. В общем я думаю нужно переносить вопрос в категорию Apache, кстати UTF-8 работает на ура!

-~{}~ 13.10.04 20:13:

В общем я конечно могу ошибаться, но походу Apache не забирает много байтовые символы, в этом дело!
 

SiMM

Новичок
Автор оригинала: nut
Дело в том, что не читается не только пробел, но и цифры, 1,2 и т.п.
Естесственно, ведь их представление в Unicode имеет вид %00%XX, а при "передаче" или "приёме" байт %00 превращается в байт %20, и обратное преобразование выполняется уже с неверными данными
В общем я конечно могу ошибаться, но походу Apache не забирает много байтовые символы, в этом дело!
Дело именно в %00, ИМХО - UTF8 ведь работает? А ведь тоже кодировка в общем случае многобайтовая.
PS: было бы лучше, если бы ты наконец указал, откуда у тебя приходят данные - может, проблема вполне разрешима на стороне клиента, причём, клиент этого даже не заметит.

-~{}~ 14.10.04 08:50:

Лирическое дополнение: похоже, это всё же PHP постарался, поскольку в $_SERVER['CHARSET_SAVED_QUERY_STRING'] строка запроса лежит в первозданном виде - можешь воспользоваться в качестве лекарства ;)
/me посыпает голову пеплом - что-то не догадался сразу [m]phpinfo[/m] посмотреть ;)
 

nut

Новичок
Большое спасибо, но как получить переменную $_SERVER['CHARSET_SAVED_QUERY_STRING'] у меня ее нет:( Может быть нужно включить какую библиотеку, или нужна новая версия php?
Есть переменная $_SERVER['QUERY_STRING'].

-~{}~ 15.10.04 09:54:

Дело то вот в чем, я беру строку из лога апача, и всеравно не могу ее декодировать, ведь php не работает до Apachе?! Ведь так? Т.е. в переменной $_SERVER['CHARSET_SAVED_QUERY_STRING'] уже болжен быть запорченный запрос. Или я что-то не понимаю.
 

SiMM

Новичок
nut, думаю, дальше тебе придётся напрячься самостоятельно - методологию я тебе дал. Всё это я проделывал на localhost под WinXP/Win98 с Apache/1.3.22 и PHP/4.3.9 как модуль - переменная там присутствует, но только в случае, если в строке запроса пытаются передать символ с кодом ноль (http://localhost/info.php?q=), в противном случае она неопределена. Посмотрел сейчас на двух серверах (Linux, Apache 1.3.31, PHP 4.3.4/CGI и Linux, Apache 1.3.31, PHP 4.3.9/module) - там %00 не перекодируется в %20 в QUERY_STRING'е, и указанного параметра так же нет - возможно, вышеописанное происходит только в версии под Windows. Как лекарство могу предложить следующую строчку кода:
PHP:
if (isset($_SERVER['CHARSET_SAVED_QUERY_STRING']) parse_str($_SERVER['CHARSET_SAVED_QUERY_STRING'],$_GET);
Кроме того, заметил, что под виндой Apache похоже вообще не отдаёт пользователю html-контент, содержащий в себе символ с кодом 0 (т.е. echo "\x0" выдаст в браузер клиента пробел).
PS: в CHARSET_SAVED_QUERY_STRING должен быть как раз таки ещё не запорченный запрос.
 
Сверху