Laravel Helper - Str::limit() 在中文應用場景的大小事
Laravel Helper - Str::limit() 在中文應用場景的大小事
最近在開發上遇到了要擷取中文訊息內容預覽的問題,例如今天我有一個句子
萊布尼茨和牛頓都被普遍認為是獨立的微積分發明者。牛頓最先將微積分應用到普通物理當中,而萊布尼茨創作了不少今天在微積分所使用的符號。牛頓、萊布尼茨都給出了微分、積分的基本規則,二階與更高階導數,近似多項式級數的記法等。在牛頓的時代,微積分基本定理是已知的事實。
擷取自 微積分 wiki
這很可能是某個文章的內容,而我在顯示頁面上的預覽只有要顯示部分的文字,例如前十個字好了,而且我想讓被隱藏的文字用「…」代替,我想顯示的內容大概如下
萊布尼茨和牛頓都被普…
這時候我們就需要用到 Laraevl Helper 裡面幫我們預先寫好的字串處理函式了
我們要使用的是 Str::limit()
這個函式,它可以幫助我們擷取某個字串的前幾個字,並且可以自定義超過字數之後的結尾
Str::limit
先來看看官網的例子
1 | use Illuminate\Support\Str; |
但是當我們的文字是中文的時候,使用起來結果會如下
1 | use Illuminate\Support\Str; |
結果跟我們預想的差蠻多的,明顯比我們想要限制的10的字還要少,所以我們就來研究一下背後到底做了什麼事情
首先,我們先去找到 Str::limit()
的 source code
Str::limit()
1 | /** |
$end
首先我們可以注意一下 input 最後一個變數 $end
,在上面的例子中都沒有賦予 $end
值,但這邊是可以給他設定值的,給了設定值之後結尾的 “…” 就可以被置換成你想要換的字串
1 | use Illuminate\Support\Str; |
中文字串字數判定
接著我們看到 11 行的位置
這邊的用意是當我給定的字串 $value
比我想要擷取的字串長度還要來得短的時候,就直接回傳原本的結果(並且不會加上 $end
)
這邊值得注意的是用來判斷字串長度的 mb_strwidth()
,我們來看一下 php 官方的文件
mb_strwidth ( string $string , string|null $encoding = null ) : int
Returns the width of string string, where halfwidth characters count as 1, and fullwidth characters count as 2. See » http://www.unicode.org/reports/tr11/ for details regarding East Asian character widths.
大致上的意思就是當你輸入的文字為半形的時候,他會回傳 1,而當你輸入的文字是全形的時候,就會回傳 2,也就是說,當我輸入「你好」的時候,我會得到 4 的回傳值
而底下 15 行的位置 使用到的 mb_strimwidth()
也是同理,我們來看一下文件的描述
mb_strimwidth ( string $string , int $start , int $width , string $trim_marker = “” , string|null $encoding = null ) : string
Truncates string string to specified width, where halfwidth characters count as 1, and fullwidth characters count as 2. See » http://www.unicode.org/reports/tr11/ for details regarding East Asian character widths.
1 |
|