首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Laravel 與 CodeIgniter 字串截取輔助函數對照:mb_strimwidth vs 正則詞界截斷

     編輯:PHP 綜合知識

字串截取是後端輸出摘要、列表標題常見需求。Laravel 內建 Str::limit()、CodeIgniter 提供 word_limiter(),兩者實作邏輯迥異:前者以字元寬度(支援中文全形)精準截斷,後者以單字邊界(英文單字)為單位。本文對照原始碼、解析差異、提供統一介面封裝建議,助你跨框架移植或自建通用工具函式。

原始碼對照

Laravel Str::limit()(Illuminate\Support\Str)

// 簡化版核心邏輯
public static function limit(string $value, int $limit = 100, string $end = '...'): string
{
    if (mb_strwidth($value, 'UTF-8') <= $limit) {
        return $value;
    }
    // mb_strimwidth 按「視覺寬度」截取:半形=1、全形=2
    return rtrim(mb_strimwidth($value, 0, $limit, '', 'UTF-8')) . $end;
}

CodeIgniter 3 word_limiter()

if (!function_exists('word_limiter')) {
    function word_limiter(string $str, int $limit = 100, string $endChar = '…'): string
    {
        if (trim($str) === '') return $str;

        // 正則匹配前 N 個「單字」(非空白序列)
        preg_match('/^\s*+(?:\S++\s*+){1,' . (int)$limit . '}/', $str, $matches);

        // 若未截斷(原字串長度等於匹配長度),不加尾碼
        if (strlen($str) === strlen($matches[0])) {
            $endChar = '';
        }
        return rtrim($matches[0]) . $endChar;
    }
}

核心差異深度解析

維度Laravel Str::limitCodeIgniter word_limiter
計數單位視覺寬度(mb_strwidth)單字數量(正則 \S+)
中文處理每個中文字算 2 寬度,精準控制顯示寬度視為一個「單字」,若限制 10 個單字,10 個中文字即達標
截斷位置可能在字元中間(需 rtrim 清理)單字邊界,不會斷字
適用場景中英混排、固定寬度版面、摘要顯示英文為主、按單字數截取、SEO 友善摘要
效能mbstring 函式,極快正則匹配,稍慢但可忽略
多位元組安全完整支援 UTF-8依賴 PCRE UTF-8 模式(需 u 修飾符)

實測對比

$text = 'Laravel 框架優雅簡潔,適合快速開發應用。';

echo 'Laravel limit(20): ' . \Illuminate\Support\Str::limit($text, 20) . "\n";
// 輸出:Laravel 框架優雅… (視覺寬度 20,含尾碼)

echo 'CI word_limiter(8): ' . word_limiter($text, 8) . "\n";
// 輸出:Laravel 框架優雅簡潔,適合快速… (前 8 個單字)

統一介面封裝建議

專案若同時維護 Laravel 與 CI 代碼,建議建立共用 StringHelper:

<?php
namespace App\Helpers;

class StringHelper
{
    /** 按視覺寬度截取(中文友善) */
    public static function byWidth(string $str, int $width, string $suffix = '...'): string
    {
        if (mb_strwidth($str, 'UTF-8') <= $width) return $str;
        return rtrim(mb_strimwidth($str, 0, $width, '', 'UTF-8')) . $suffix;
    }

    /** 按單字數截取(英文友善) */
    public static function byWords(string $str, int $words, string $suffix = '…'): string
    {
        if (trim($str) === '') return $str;
        preg_match('/^\s*+(?:\S++\s*+){1,' . (int)$words . '}/u', $str, $m);
        if (strlen($str) === strlen($m[0])) $suffix = '';
        return rtrim($m[0]) . $suffix;
    }

    /** 智能截取:中文優先用寬度,英文優先用單字 */
    public static function smartLimit(string $str, int $limit, string $suffix = '...'): string
    {
        // 簡單啟發式:若含中文(\p{Han})用寬度,否則用單字
        if (preg_match('/\p{Han}/u', $str)) {
            return self::byWidth($str, $limit, $suffix);
        }
        return self::byWords($str, $limit, $suffix);
    }
}

進階:HTML 內容安全截取

若輸入含 HTML 標籤,直接截取會破壞結構。建議流程:

  1. strip_tags() 移除標籤(或保留允許標籤)
  2. html_entity_decode() 還原實體
  3. 套用上述截取函式
  4. 輸出時 htmlspecialchars() 防 XSS

或使用成熟套件:htmlburger/cut-html、spatie/html-element。

總結

  • Laravel Str::limit:視覺寬度導向,中英混排首選,mb_strimwidth 核心。
  • CI word_limiter:單字邊界導向,英文內容首選,正則核心。
  • 選型原則:中文多用寬度、英文多用單字、通用場景可自建智能切換封裝。
  • 避坑:HTML 內容必須先淨化再截取,輸出必須轉義。

掌握兩大框架截取邏輯本質,讓你在遷移、整合、自建工具時遊刃有餘,輸出優雅且安全的字串摘要。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved