Open ershiwo opened 8 years ago
让我来猜 Bangumi 的源代码 (bgm38) 推测如下:
$sign = $_POST['sign'];
if(strlen($sign) > 50) {
$sign = mb_substr($sign, 0, 50, 'utf-8') . ' ...';
}
写了一个解
$sign = $_POST['sign'];
$result = '';
$resultLength = 0;
$mbLength = mb_strlen($str, 'utf-8')
for($i = 0; $i < $mbLength; $i++) {
$tmp = mb_substr($str, $i, 1, 'utf-8');
$resultLength += (strlen($tmp) === mb_strlen($tmp, 'utf-8')) ? 1 : 2;
$result .= $tmp;
if($resultLength >= 50) {
$result .= ' ...';
break;
}
}
但是似乎并不能解释自动更新的问题……
回信请加在信件顶部。
假設我們以第一段程序來運作,傳入的值是「巨硬信仰充值完毕,要不要坐下来盘昆特牌? ...」 運行下列程序:
$sign = $_POST['sign'];
if(strlen($sign) > 50) { //由於此處長度是「64」,所以會進入 if 內
$sign = mb_substr($sign, 0, 50, 'utf-8') . ' ...'; //這時候以 mb_substr 取出來的前 50 字是「巨硬信仰充值完毕,要不要坐下来盘昆特牌? ...」,又 Append 了一組「 ...」了。
}
由於 strlen 所計算的是「字節數」,對於中日韓文來說,一個字符可能是二或三個字節(ANSI 或 UTF-8),所以在程序第二行得出的長度是 64 (20 個中文字 * 3 + 4 個 ASCII 字符 = 64) 關於解法我在上一封回信內有提到,這裡再對源代碼做解釋:
$sign = $_POST['sign'];
$result = '';
$resultLength = 0;
$mbLength = mb_strlen($str, 'utf-8')
for($i = 0; $i < $mbLength; $i++) { //嘗試針對輸入的每一個「字」(多字節字符算一個字)進行操作
$tmp = mb_substr($str, $i, 1, 'utf-8');
$resultLength += (strlen($tmp) === mb_strlen($tmp, 'utf-8')) ? 1 : 2; //若 strlen 取得的長度與 mb_strlen 取得的長度相同代表他是一個 ASCII 字符(半角字符),若否則代表是一個多字節字符(大部分情況下是全角,例外可能是半角的カタカナ,總之這裡當 2 去計算)
$result .= $tmp; //將當前遍歷到的字符串上去
if($resultLength >= 50) { //最後這裡判斷到目前為止拼上去字符串的長度(全角字符算 2 ,半角字符算 1),若全部大於 50 就停止
$result .= ' ...';
break;
}
}
也就是说,当时没考虑 CJK 编码的特殊性,导致设定的允许字符数小了。如果是这样的话应该加一行截断再输出“…”的。
直接截断 ...
也是不行的,因为限制是「50字」,
如果是这句话 起来,饥寒交迫的奴隶,起来,全世界受苦的人
这一段文字虽然只有 21 个字,
但是 strlen 算出来的长度是 63 个字,超过 50 了,
所以通过 mb_substr($sign, 0, 50, 'utf-8')
截断前 50 个字并串上 ...
,
在这里对 mb_substr 来说,算出来的长度是 21 哦!所以取前 50 个字就等于取全部了。
下一次再提交的时候,你的签名会是 起来,饥寒交迫的奴隶,起来,全世界受苦的人 ...
,
strlen 算出来长度是 67,同样超过 50 ,所以截断,
截断了前 50 个字,还是 起来,饥寒交迫的奴隶,起来,全世界受苦的人 ...
,然后又给你串了一次 ...
,
所以在签名是中文时,这样子并不是正常情况,
正常情况应该是像这个样子:
输入字串为「Lorem ipsum dolor sit amet, consectetur adipiscing volutpat.」这里总共有 60 个字,
通过 strlen 算出来的长度是 60 ,超过 50 了,
所以通过 mb_substr($sign, 0, 50, 'utf-8')
截断前 50 个字并串上 ...
,
这时候你的签名会变成这样:Lorem ipsum dolor sit amet, consectetur adipiscing ...
下一次你提交的时候再通过一样的过程:
通过 strlen 算出来的长度是 54 ,超过 50,所以截断再串上 ...
,
截断 50 个字的时候就是 Lorem ipsum dolor sit amet, consectetur adipiscing
,所以并不会出现两次 ...
。
启用了 BHC,症状是新出现的。 具体表现就是在更新过一次签名之后,这两天每天 0 点左右都会在时间线上看见自己的签名被自动更新并加上了一个“...”,已经和 @BinotaLiu 确认了不是 BHC 的问题,所以提交一下。 update: 只要进入一次设置页面,不管是否有操作,退出后就会自动更新签名了。