Как читать символы, отличные от ASCII, из стандартного ввода CLI
Если я набираю å
в CMD, fgets перестает ждать большего ввода и цикл работает до тех пор, пока я не нажму ctrl-c
. Если я нахожу "нормальные" символы, такие как a-z0-9!?(), Он работает так, как ожидалось.
Я запускаю код в CMD под Windows 7 с UTF-8 как charset (chcp 65001
), файл сохраняется как UTF-8 без bom. Я использую PHP 5.3.5 (cli).
<?php
echo "ÅÄÖåäö work here.\n";
while(1)
{
echo '> '. fgets(STDIN);
}
?>
Если я изменяю кодировку на chcp 1252
, цикл не прерывается, когда я набираю å
и печатаю " > å", но работа "ÅÄÖåäö здесь" становится "Ã... Ã" Ã-à ¥ äà ¶ работать здесь!". И я знаю, что я могу изменить файл в ANSI, но тогда я не могу использовать специальные символы, такие как ╠╦╗.
Итак, почему fgets перестают ждать ввода userinput после того, как я набрал åäö?
И как я могу это исправить?
EDIT:
Также обнаружена странная ошибка.
echo "öäåÅÄÖåäö work here! Or?".chr(10);
→ ��äåÅÄÖåäö work here! Or? re! Or?
.
Если первый char в эхо составляет å/ä/ö
, он печатает странные символы и конец выходного дубликата с n - 1
char.. (n = число åäö в начале строки).
Например: echo "åäö 1234" -> ??äö 123434
и echo åäöåäö 1234
→ ??äöåäö 1234 1234
.
EDIT2 (разрешено):
Проблема была chcp 65001
, теперь я использую chcp 437
(chcp 437).
Большое спасибо Тимоти Мартенсу!
Ответы
Ответ 1
Возможное решение:
echo '>';
$line = stream_get_line(STDIN, 999999, PHP_EOL);
Примечания:
Я не смог воспроизвести вашу ошибку, используя несколько версий PHP.
Использование следующей версии PHP 5.3.8 не вызывало у меня проблем
PHP 5.3 (5.3.8) VC9 x86 Non Thread Safe (2011-авг-23 12:26:18) Arcitechture - Win XP SP3 32 бит
Вы можете попробовать обновить PHP.
Я загрузил php-5.3.5-nts-Win32-VC6-x86 и не смог воспроизвести вашу ошибку, он отлично работает для меня.
Изменить: Дополнительно я набрал символы, используя мою испанскую клавиатуру.
Edit2:
Команда CMD:
chcp 437
Код PHP:
<?php
$fp=fopen("php://stdin","r");
while(1){
$str = fgets(STDIN);
echo mb_detect_encoding($str)."\n";
echo '>'.stream_get_line($fp,999999,"\n")."\n";
}
?>
Вывод:
test
ASCII
test
>test
öïü
öïü
>öïü
Ответ 2
Я думаю, это происходит потому, что PHP 5.3 не поддерживает правильно многобайтовые символы.
Эти символы: ÅÄÖåäö
Являются бинарными: c3 85 c3 84 c3 96 c3 a5 c3 a4 c3 b6
(без спецификации при начале)
Цитирование Строка PHP:
Строка - это серия символов, где символ совпадает с байтом. Это означает, что PHP поддерживает только 256-символьный набор и, следовательно, не предлагает поддержку родного Unicode. Подробнее о типе строки.
Обычно не влияет на конечный результат, потому что браузер/читатель понимает многобайтовые символы, но для CMD и STDIN-буфера есть ÅÄÖåäö
(12 символов/байт char).
только Функции MB обрабатывают основные операции с несколькими байтами.