6

ASCIIおよびUTF-8文字列のバイト数を決定するために、php.netサイトから次の関数があります。

<?php 
/** 
 * Count the number of bytes of a given string. 
 * Input string is expected to be ASCII or UTF-8 encoded. 
 * Warning: the function doesn't return the number of chars 
 * in the string, but the number of bytes. 
 * 
 * @param string $str The string to compute number of bytes 
 * 
 * @return The length in bytes of the given string. 
 */ 
function strBytes($str) 
{ 
  // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT 

  // Number of characters in string 
  $strlen_var = strlen($str); 

  // string bytes counter 
  $d = 0; 

 /* 
  * Iterate over every character in the string, 
  * escaping with a slash or encoding to UTF-8 where necessary 
  */ 
  for ($c = 0; $c < $strlen_var; ++$c) { 

      $ord_var_c = ord($str{$d}); 

      switch (true) { 
          case (($ord_var_c >= 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; 
} 
?> 

ただし、ロシア語でこれを試すと(例По своей природе компьютеры могут работать лишь с числами. И для того, чтобы они могли хранить в памяти буквы или другие символы, каждому такому символу должно быть поставлено в соответствие число.)。正しいバイト数を返していないようです。

switch ステートメントはデフォルトの条件を使用しています。ロシア語の文字が期待どおりに機能しない理由はありますか? または、これにはより良いオプションがありますか。

UTF-8 文字列を特定のバイト数に短縮する必要があるため、これを求めています。つまり、最大値しか送信できません。私の状況では、169 バイトの JSON データを iPhone APNS に転送します (他のパケット データを除く)。

参照: PHP strlen - マニュアル (Paolo Comment on 10-Jan-2007 03:58)

4

5 に答える 5

5

utf-8 文字列を特定のバイト数に短縮する必要があるため、これを求めています。

mb_strcut()ほとんど理解できないドキュメントからはわからないかもしれませんが、まさにこれを行います。

于 2010-03-05T11:51:06.330 に答える
2

strlen() はバイト数を返します。

マルチバイト文字列を特定のバイト数に短縮することは、別のタスクです。文字列を短くするときに、マルチバイト シーケンスの途中で文字列を切り落とさないように注意する必要があります。

処理する必要があるもう 1 つのことは、文字列を json 表記に入れると、それを json として表すためにさらにバイトが必要になる場合があることです。たとえば、文字列に二重引用符が含まれているとします。エスケープする必要があり、バックスラッシュ文字は 1 バイト追加されます。エスケープする必要がある他の文字もあります。ポイントは、大きくなる可能性があることです。バイト制限はjsonペイロードの合計にあると想定しているため、json構文自体と、jsonが文字列に課すエスケープを考慮する必要があります。

最適化されていないちょっとハックな方法は、substr() を使用して、制限よりも 5 バイト多い文字列を切り刻むことです。mb_strlen() を使用して文字数を取得し、mb_substr() を使用して最後の文字を削除します。これを json としてエンコードし、strlen() を介してバイトを測定します。mb_substr() を使用して最後の文字を切り落とし、json としてエンコードし、strlen() を使用して再度バイトを測定するループに入ります。バイト数が許容範囲内になると、ループは終了します。

于 2010-03-05T07:35:48.580 に答える
1

mbstring.func_overload 2 および UTF-8 文字列を使用しているときにマルチバイト文字列のバイト長を調べたい場合は、次を使用できます。

mb_strlen($utf8_string, 'latin1');
于 2010-03-05T03:04:07.250 に答える
1

PHP 5 ではmb_strlen、文字数を返す必要があります。strlenバイト数を返す必要があります。

たとえば、コードのこの部分:

$string = 'По своей природе компьютеры могут работать лишь с числами. И для того, чтобы они могли хранить в памяти буквы или другие символы, каждому такому символу должно быть поставлено в соответствие число';
echo mb_strlen($string, 'UTF-8') . '<br />';
echo strlen($string);

次の出力が得られるはずです。

196
359


補足として: これは PHP 6 で変更されることの 1 つです: PHP 6 はデフォルトで Unicode を使用します。つまりstrlen、PHP 6 では、バイト数ではなく、文字数を返す必要があります。

于 2010-03-05T05:27:01.533 に答える
0

バイト数 <> 文字列の長さ!

使用できるバイト数を取得するには、(php4,5) strlen. Unicode 文字列 (utf8 でエンコードされた) の長さを取得するには、mb_strlen を使用するか (その拡張子からの関数のオーバーロードに注意してください)、または 8 番目のビットが設定されていないすべてのバイトを単純に数えることができます。

この unicodechar の 8 番目のビットは、入力から少なくとももう 1 バイト来ていることを意味します。

于 2010-03-05T13:18:38.897 に答える