我在php.net网站上有以下函数来确定ASCII和UTF-8字符串中的字节数:
<?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(不包括其他数据包数据)。
答案 0 :(得分:4)
我问这个,因为我需要缩短 一个utf-8字符串到一定数量的 字节。
mb_strcut()
正是这样做的,尽管你可能无法从几乎无法理解的文档中说出来。
答案 1 :(得分:2)
strlen()返回字节数。
将多字节字符串缩短为特定字节数是一项单独的任务。在缩短它时,您需要注意不要在多字节序列的中间切断字符串。
您需要处理的另一件事是,当您将字符串放入json表示法时,可能需要更多字节来将其表示为json。例如,如果您的字符串包含双引号字符。它需要被转义,反斜杠字符将添加一个字节。还有其他角色也需要转义。重点是,它可以变得更大。我假设字节数限制在总json有效负载上,因此您需要考虑json语法本身,以及json将对您的字符串强加的任何转义。
一个未经优化的,有点hacky的方法是使用substr()来切断字符串,比你的限制多5个字节。现在使用mb_strlen()获取字符数,使用mb_substr()删除最后一个字符。现在将其编码为json,并通过strlen()测量字节。输入一个循环,它使用mb_substr()保持切断最后一个字符,编码为json,然后使用strlen()再次测量字节。当字节数可以接受时,循环终止。
答案 2 :(得分:1)
如果您希望在使用mbstring.func_overload 2和UTF-8字符串时找到多字节字符串的字节长度,则可以使用以下内容:
mb_strlen($utf8_string, 'latin1');
答案 3 :(得分:1)
在PHP 5中,mb_strlen
应该返回字符数;并且strlen
应该返回字节数。
例如,这部分代码:
$string = 'По своей природе компьютеры могут работать лишь с числами. И для того, чтобы они могли хранить в памяти буквы или другие символы, каждому такому символу должно быть поставлено в соответствие число';
echo mb_strlen($string, 'UTF-8') . '<br />';
echo strlen($string);
应该得到以下输出:
196
359
作为旁注:这是PHP 6将要改变的事情之一:默认情况下PHP 6将使用Unicode,这意味着{6}中的strlen
应该返回字符数,而不是字节数了。
答案 4 :(得分:0)
字节数&lt;&gt;字符串长度!
获取可以使用的字节数(php4,5)strlen。 要获得unicode字符串(utf8编码)长度,你可以使用mb_strlen(注意来自该扩展的函数重载),或者你可以简单地计算所有没有设置第8位的字节。
第8位表示此unicodechar至少还有一个来自输入的字节。