【发布时间】:2011-01-23 23:08:54
【问题描述】:
我从 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 字符串缩短到一定数量的字节。即我只能发送一个最大值。在我的情况下,向 iPhone APNS 发送 169 字节的 JSON 数据(不包括其他数据包数据)。
【问题讨论】:
-
开关(真)?这是一种奇怪的做事方式..
-
该功能来自帖子底部参考中的评论。我没有编码 :) 但是看起来它是在正确的过程中,而不是使用 mb_strlen,除了俄语字符不起作用。
-
@Brendan 我只是在想同样的事情。
-
@BrendanLong
switch(true)有什么奇怪的地方? -
是吗?恕我直言,如果您有多个
elseifs,您应该尽可能使用switch(),就像在OP 中一样。也许这只是我。 :)
标签: php string utf-8 byte strlen