согласно ISO 8859-1
€ Символ имеет десятичное значение 128
Моя кодировка php-скрипта по умолчанию
echo mb_internal_encoding(); //ISO-8859-1
Итак, теперь, когда PHP
echo chr(128); //Output exactly what i want '€'
Но
echo ord('€'); //opposite it returns 226, it should be 128
почему это так?
Согласно Wikipedia и FileFormat ,
0xA4
) 0x80
) 0x20AC
8364 ( 0x20AC
) 0xE2 0x82 0xAC
. Первый байт E2
равен 226 в десятичном значении. Таким образом, кажется, что ваш исходный файл закодирован в UTF-8 (и ord()
возвращает только первый байт), тогда как ваш вывод находится в Windows-1252.
echo ord('€'); //opposite it returns 226, it should be 128
Ваш .php-файл сохраняется как UTF-8 (вы сохранили его как UTF-8 в текстовом редакторе при сохранении файла на диске). Строковый литерал там содержит байты E2 82 AC
; визуализировал это что-то вроде этого:
echo ord('\xE2\x82\xAC');
Откройте файл в шестнадцатеричном редакторе для реальной ясности.
ord
возвращает только одно целое число в диапазоне от 0 до 255. Ваш строковый литерал содержит три байта, для которых ord
должен возвращать три целых числа, а это не будет. Он возвращает только первый, который равен 226
.
Сохраните файл в разных кодировках в текстовом редакторе, и вы увидите разные результаты.
Эта функция PHP возвращает десятичное число первого символа в строке.
function ord_utf8($s){ return (int) ($s=unpack('C*',$s[0].$s[1].$s[2].$s[3]))&&$s[1]<(1<<7)?$s[1]: ($s[1]>239&&$s[2]>127&&$s[3]>127&&$s[4]>127?(7&$s[1])<<18|(63&$s[2])<<12|(63&$s[3])<<6|63&$s[4]: ($s[1]>223&&$s[2]>127&&$s[3]>127?(15&$s[1])<<12|(63&$s[2])<<6|63&$s[3]: ($s[1]>193&&$s[2]>127?(31&$s[1])<<6|63&$s[2]:0))); } echo ord_utf8('€'); // Output 8364 then this character is encoded in 3 octets
Вы можете проверить результат в https://eval.in/748181 …
Функция ord_utf8 является обратной величиной chr_utf8 (печатает один символ utf8 из десятичного числа)
function chr_utf8($n,$f='C*'){ return $n<(1<<7)?chr($n):($n<1<<11?pack($f,192|$n>>6,1<<7|191&$n): ($n<(1<<16)?pack($f,224|$n>>12,1<<7|63&$n>>6,1<<7|63&$n): ($n<(1<<20|1<<16)?pack($f,240|$n>>18,1<<7|63&$n>>12,1<<7|63&$n>>6,1<<7|63&$n):''))); } for($test=1;$test<1114111;$test++) if (ord_utf8(chr_utf8($test))!==$test) die('Error found'); echo 'No error'; // Output No error