Как я нахожу число байтов в строке UTF-8 с PHP?

У меня есть следующая функция от сайта 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)

6
задан Alan Moore 5 March 2010 в 13:09
поделиться

5 ответов

strlen() возвращает количество байт.

Сокращение многобайтовой строки до определенного количества байт - это отдельная задача. Вам нужно будет позаботиться о том, чтобы при сокращении не оборвать строку в середине многобайтовой последовательности.

Другая вещь, с которой вам нужно справиться, заключается в том, что когда вы переводите строку в нотацию json, для ее представления в виде json может потребоваться больше байт. Например, если ваша строка содержит символ двойной кавычки. Его нужно экранировать, и символ обратной косой черты добавит один байт. Есть и другие символы, которые тоже нужно экранировать. Суть в том, что она может стать больше. Я предполагаю, что ограничение в байтах касается общего объема json, поэтому вам нужно учесть синтаксис самого json, а также любые экранирующие символы, которые json будет накладывать на вашу строку.

Неоптимизированный и довольно хакерский способ сделать это - разрезать строку, скажем, на 5 байт больше вашего лимита, используя substr(). Теперь используйте mb_strlen(), чтобы получить количество символов, и mb_substr(), чтобы удалить последний символ. Теперь закодируйте его как json и измерьте количество байт с помощью strlen(). Введите цикл, который продолжает отсекать последний символ с помощью mb_substr(), кодировать в json и снова измерять байты с помощью strlen(). Цикл завершается, когда количество байтов становится приемлемым.

2
ответ дан 10 December 2019 в 02:46
поделиться

Я спрашиваю об этом, поскольку мне нужно сократить строку в формате utf-8 до определенного количества байт.

mb_strcut() делает именно это, хотя вы, возможно, не сможете понять это из едва понятной документации.

5
ответ дан 10 December 2019 в 02:46
поделиться

В 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 возвращать количество символов, а не количество байт.

1
ответ дан 10 December 2019 в 02:46
поделиться

Если вы хотите найти длину байта многобайтовой строки при использовании mbstring.func_overload 2 и строк UTF-8, то вы можете использовать следующее:

mb_strlen($utf8_string, 'latin1');
1
ответ дан 10 December 2019 в 02:46
поделиться

Количество байтов <> Длина строки!

, чтобы получить количество байтов, вы можете использовать (php4,5) strlen. чтобы получить длину строки Unicode (в кодировке utf8), вы можете использовать mb_strlen (позаботьтесь о перегрузке функций из этого расширения) или вы может просто подсчитать все байты, для которых не установлен 8-й бит.

8-й бит означает, что для этого Unicodechar идет как минимум еще один байт из ввода.

0
ответ дан 10 December 2019 в 02:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: