У меня есть следующая функция от сайта php.net для определения # байтов в строке UTF-8 и ASCII:
= 0x20) && ($ord_var_c <= 0x7F)):
// characters U-00000000 - U-0000007F (same as ASCII)
$d++;
break;
case (($ord_var_c & 0xE0) == 0xC0):
// characters U-00000080 - U-000007FF, mask 110XXXXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$d+=2;
break;
case (($ord_var_c & 0xF0) == 0xE0):
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$d+=3;
break;
case (($ord_var_c & 0xF8) == 0xF0):
// characters U-00010000 - U-001FFFFF, mask 11110XXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$d+=4;
break;
case (($ord_var_c & 0xFC) == 0xF8):
// characters U-00200000 - U-03FFFFFF, mask 111110XX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$d+=5;
break;
case (($ord_var_c & 0xFE) == 0xFC):
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$d+=6;
break;
default:
$d++;
}
}
return $d;
}
?>
Однако, когда я пробую это русским языком (например. По своей природе компьютеры могут работать лишь с числами. И для того, чтобы они могли хранить в памяти буквы или другие символы, каждому такому символу должно быть поставлено в соответствие число.
). Это, кажется, не возвращает корректное число байтов.
Оператор переключения использует условие по умолчанию. Какие-либо идеи, почему российские символы не работали бы как ожидалось? Или там были бы более оптимальные варианты для этого.
Я спрашиваю это, поскольку я должен укоротить строку UTF-8 к определенному числу байтов. т.е. Я могу только отправить максимум 169 байтов данных JSON к iPhone APNS в моей ситуации (исключая другие пакетные данные).
Ссылка: PHP strlen - Руководство (Комментарий паоло 10 января 2007 3:58)
strlen() возвращает количество байт.
Сокращение многобайтовой строки до определенного количества байт - это отдельная задача. Вам нужно будет позаботиться о том, чтобы при сокращении не оборвать строку в середине многобайтовой последовательности.
Другая вещь, с которой вам нужно справиться, заключается в том, что когда вы переводите строку в нотацию json, для ее представления в виде json может потребоваться больше байт. Например, если ваша строка содержит символ двойной кавычки. Его нужно экранировать, и символ обратной косой черты добавит один байт. Есть и другие символы, которые тоже нужно экранировать. Суть в том, что она может стать больше. Я предполагаю, что ограничение в байтах касается общего объема json, поэтому вам нужно учесть синтаксис самого json, а также любые экранирующие символы, которые json будет накладывать на вашу строку.
Неоптимизированный и довольно хакерский способ сделать это - разрезать строку, скажем, на 5 байт больше вашего лимита, используя substr(). Теперь используйте mb_strlen(), чтобы получить количество символов, и mb_substr(), чтобы удалить последний символ. Теперь закодируйте его как json и измерьте количество байт с помощью strlen(). Введите цикл, который продолжает отсекать последний символ с помощью mb_substr(), кодировать в json и снова измерять байты с помощью strlen(). Цикл завершается, когда количество байтов становится приемлемым.
Я спрашиваю об этом, поскольку мне нужно сократить строку в формате utf-8 до определенного количества байт.
mb_strcut()
делает именно это, хотя вы, возможно, не сможете понять это из едва понятной документации.
В PHP 5, mb_strlen
должен возвращать количество символов, а strlen
- количество байт.
Например, эта часть кода :
$string = 'По своей природе компьютеры могут работать лишь с числами. И для того, чтобы они могли хранить в памяти буквы или другие символы, каждому такому символу должно быть поставлено в соответствие число';
echo mb_strlen($string, 'UTF-8') . '<br />';
echo strlen($string);
Должна дать следующий результат :
196
359
В качестве примечания: это одна из вещей, которую изменит PHP 6: PHP 6 будет использовать Unicode по умолчанию, что означает, что strlen
должен в PHP 6 возвращать количество символов, а не количество байт.
Если вы хотите найти длину байта многобайтовой строки при использовании mbstring.func_overload 2 и строк UTF-8, то вы можете использовать следующее:
mb_strlen($utf8_string, 'latin1');
Количество байтов <> Длина строки!
, чтобы получить количество байтов, вы можете использовать (php4,5) strlen. чтобы получить длину строки Unicode (в кодировке utf8), вы можете использовать mb_strlen (позаботьтесь о перегрузке функций из этого расширения) или вы может просто подсчитать все байты, для которых не установлен 8-й бит.
8-й бит означает, что для этого Unicodechar идет как минимум еще один байт из ввода.