您好,登錄后才能下訂單哦!
什么是ThinkSNS+
ThinkSNS(簡(jiǎn)稱(chēng)TS),一款全平臺(tái)綜合性社交系統(tǒng),為國(guó)內(nèi)外大中小企業(yè)和創(chuàng)業(yè)者提供社會(huì)化軟件研發(fā)及技術(shù)解決方案,目前最新版本為T(mén)hinkSNS+、ThinkSNS V4、ThinkSNS【簡(jiǎn)】。
今天我們來(lái)聊一下可能很多人都會(huì)頭疼的東西:顯示長(zhǎng)度。
需求是這樣的,在字符的顯示上,兩個(gè)英文單詞才占一個(gè)中文或者其他語(yǔ)言的顯示長(zhǎng)度。如下:
ab
哈
?
上面排的是兩個(gè)英文字母,一個(gè)漢字,一個(gè)Emoji。你會(huì)發(fā)現(xiàn),在顯示上占的寬度是一致的。一些設(shè)計(jì)上為了好看也要求有這樣的處理。
例如,我們的用戶名需求是最多12個(gè)非單字節(jié)字符或者24個(gè)單字節(jié)字符的需求也可以混合排的需求,我們寫(xiě)后端不得不處理這樣的驗(yàn)證了。
需求規(guī)則是 /^[a-zA-Z\x7f-\xff][a-zA-Z0-9\x7f-\xff]*$/
在ThinkSNS+中,為了能把這部分驗(yàn)證公用,所以選擇使用自定義驗(yàn)證規(guī)則。我們先說(shuō)下計(jì)算的實(shí)現(xiàn)思路吧!
首先,就算是mb_strlen也沒(méi)法準(zhǔn)確的獲取多字節(jié)字符和單子節(jié)字符混合在一起的長(zhǎng)度,網(wǎng)上有個(gè)說(shuō)法,漢字占三個(gè)字節(jié),英文數(shù)組半角符號(hào)占一個(gè)字節(jié),所以:
`(mb_strlen($str) + strleng($str)) / 2`
用這個(gè)方法可以得到單字節(jié)占0.5多字節(jié)占1的計(jì)算。但是以中文為例,只有兩萬(wàn)個(gè)漢字才是這種情況,還有六萬(wàn)多漢字是四個(gè),其次,emoji也是四個(gè)字節(jié)。根本無(wú)法準(zhǔn)確的計(jì)算。
好在在無(wú)意間發(fā)現(xiàn)一個(gè)奇怪的東西str_word_count 這個(gè)函數(shù)計(jì)算非英文單詞外是除了符號(hào)例如中文就是按照漢字個(gè)數(shù)算的,emoji也是同理。
發(fā)現(xiàn)這個(gè)以后,咱們就好辦了。我們吧用戶名中的 [a-aA-Z0-9_] 剔除掉,單獨(dú)計(jì)算不就是我們要的驗(yàn)證長(zhǎng)度了嗎?
所以,首先我們用:
preg_match_all('/[a-zA-Z0-9_]/', $value, $single);
$single = count($single[0]) / 2;
方式單獨(dú)計(jì)算出單字節(jié)字符的顯示長(zhǎng)度,再用:
$double = str_word_count(preg_replace('([a-zA-Z0-9_])', '', $value));
方式計(jì)算出多字節(jié)的長(zhǎng)度,最后:
$length = $single + $double;
就得出了顯示長(zhǎng)度,實(shí)現(xiàn)了,最后封裝成驗(yàn)證規(guī)則:
Validator::extend('display_length', function ($attribute, $value, array $parameters) {
if (empty($parameters)) {
throw new \InvalidArgumentException('Parameters must be passed');
}
$min = 0;
if (count($parameters) === 1) {
list($max) = $parameters;
} elseif (count($parameters) >= 2) {
list($min, $max) = $parameters;
}
if (! isset($max) || $max < $min) {
throw new \InvalidArgumentException('The parameters passed are incorrect');
}
// 計(jì)算單字節(jié).
preg_match_all('/[a-zA-Z0-9_]/', $value, $single);
$single = count($single[0]) / 2;
// 多子節(jié)長(zhǎng)度.
$double = str_word_count(preg_replace('([a-zA-Z0-9_])', '', $value));
// 得出最終計(jì)算字符的長(zhǎng)度
$length = $single + $double;
return $length >= $min && $length <= $max;
});
代碼是原型代碼,還沒(méi)有進(jìn)行優(yōu)化,之后我們只要按照下面的方式用:
$rules = [
'inputKey' => 'display_length:5', // 表示 0 - 5 顯示長(zhǎng)度
‘inputkey2’ => 'display_length:4,12' // 表示顯示長(zhǎng)度為 4 - 12
];
現(xiàn)在就很好的解決了這個(gè)需求。
我們很樂(lè)意,將基于 Laravel 的 ThinkSNS+ 產(chǎn)品開(kāi)發(fā)中的技術(shù)解決方案分享給大家,也希望喜歡的朋友能給國(guó)內(nèi)開(kāi)源產(chǎn)品一點(diǎn)點(diǎn)的支持。
往期研發(fā)日記回顧:
《ThinkSNS+基于?Laravel master?分支【研發(fā)日記一】》
《ThinkSNS+研發(fā)中前端的抉擇(webpack/Vue)踩坑日記【研發(fā)日記二】》
《基于?Laravel Route?的?ThinkSNS+ Component【研發(fā)日記三】》
《如何做到?Laravel?配置可以網(wǎng)站后臺(tái)配置【研發(fā)日記四】》
開(kāi)源代碼倉(cāng)庫(kù):
GitHub:https://github.com/zhiyicx/thinksns-plus(點(diǎn)擊star,每日關(guān)注開(kāi)發(fā)動(dòng)態(tài)。)
開(kāi)源不易,為了爭(zhēng)取開(kāi)源,我們團(tuán)隊(duì)做了很多努力。把基于Laravel的作品展示在大家面前,之后專(zhuān)欄會(huì)持續(xù)不斷的分享ThinkSNS +開(kāi)發(fā)過(guò)程中的技術(shù)細(xì)節(jié)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。