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

ThinkPHP msubstr 字符截取函數完整用法與常見坑位避坑指南

     編輯:PHP 相關知識

ThinkPHP msubstr 字符截取函數完整用法與常見坑位避坑指南

msubstr 是 ThinkPHP 內置的多字節安全字符截取函數,解決 substr 截取中文亂碼問題。本文詳解語法、模板調用、核心源碼與 Linux 部署常見大小寫陷阱。

一、函數語法與參數

msubstr($str, $start = 0, $length, $charset = 'utf-8', $suffix = true)
參數說明默認值
$str待截取字符串必填
$start開始位置(0 索引)0
$length截取長度必填
$charset字符編碼'utf-8'
$suffix是否添加省略號true

二、模板中調用示例

{-- 從第 5 個字符開始,截取 5 個字符,UTF-8,不顯示省略號 --}
{$vo.title|msubstr=5,5,'utf-8',false}

{-- 從開頭截取 20 個字符,顯示省略號 --}
{$vo.content|msubstr=0,20}

{-- GBK 編碼環境 --}
{$vo.name|msubstr=0,10,'gbk',true}

三、核心源碼解析(ThinkPHP 3.2/5.0/6.0 通用邏輯)

function msubstr($str, $start = 0, $length, $charset = 'utf-8', $suffix = true) {
    // 1. 優先使用 mbstring 擴展
    if (function_exists('mb_substr')) {
        $slice = mb_substr($str, $start, $length, $charset);
        return $suffix ? $slice . '...' : $slice;
    }
    
    // 2. 其次使用 iconv
    if (function_exists('iconv_substr')) {
        $slice = iconv_substr($str, $start, $length, $charset);
        return $suffix ? $slice . '...' : $slice;
    }
    
    // 3. 純 PHP 正則兜底(性能較差)
    $re = [
        'utf-8'   => '/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/',
        'gb2312'  => '/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/',
        'gbk'     => '/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/',
        'big5'    => '/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/',
    ];
    
    preg_match_all($re[$charset], $str, $match);
    $slice = join('', array_slice($match[0], $start, $length));
    return $suffix ? $slice . '…' : $slice;
}

四、Linux 部署常見報錯:Call to undefined function msubstr()

原因分析

  1. 文件大小寫敏感:Linux 區分大小寫,Windows 不區分
  2. 公共函數文件命名:ThinkPHP 約定 Common/common.php(C 大寫目錄,小寫文件)
  3. 自動載入機制:框架只掃描符合約定的文件

錯誤示例

# 錯誤:目錄大寫,文件大寫
Common/Common.php

# 錯誤:目錄小寫
common/common.php

# 正確:目錄大寫,文件小寫
Common/common.php

解決方案

  1. 確保項目目錄結構:Application/Common/common.php
  2. 在 common.php 中定義 msubstr 函數(或引入框架核心函數庫)
  3. 清除緩存:php think clear 或刪除 Runtime/Cache/ 目錄
  4. 驗證:php -r "var_dump(function_exists('msubstr'));"

五、進階用法與替代方案

1. 控制器中直接調用

<?php
namespace app\index\controller;
use think\Controller;

class Index extends Controller {
    public function index() {
        $title = '這是一個很長的標題需要截取顯示';
        $short = msubstr($title, 0, 15, 'utf-8', true);
        $this->assign('short_title', $short);
        return $this->fetch();
    }
}

2. ThinkPHP 5/6 內置助手函數 str_limit

// TP 5.1+ 內置
str_limit($str, 20, '...'); // 等同 msubstr($str, 0, 20, 'utf-8', true)

// 更強大的字符串操作類
use think\Str;
Str::limit($str, 20);           // 截取
Str::contains($str, '關鍵詞');   // 包含檢查
Str::startsWith($str, '前綴');   // 前綴匹配
Str::endsWith($str, '後綴');     // 後綴匹配

3. 原生 PHP 8.0+ mb_substr 直接使用

// 現代 PHP 項目推薦直接使用 mbstring
mb_substr($str, 0, 20, 'UTF-8'); // 無需封裝
// 組合函數
function safe_substr($str, $len, $suffix = '...') {
    return mb_strlen($str, 'UTF-8') > $len 
        ? mb_substr($str, 0, $len, 'UTF-8') . $suffix 
        : $str;
}

六、性能對比與建議

方案性能依賴推薦場景
mb_substr⭐⭐⭐⭐⭐mbstring 擴展現代 PHP 7.2+ 項目首選
iconv_substr⭐⭐⭐⭐iconv 擴展無 mbstring 環境
msubstr (正則兜底)⭐⭐無極舊環境兼容
Str::limit (TP 5.1+)⭐⭐⭐⭐ThinkPHP 核心TP 框架項目統一規範

七、避坑清單

  1. ✅ 確認服務器安裝 php-mbstring / php-iconv
  2. ✅ 文件命名遵循 Common/common.php(目錄大寫,文件小寫)
  3. ✅ 模板修飾符參數順序:起始,長度,編碼,省略號
  4. ✅ 數據庫字段編碼與 PHP 內部編碼一致(推薦 utf8mb4)
  5. ✅ 避免在循環中大量調用正則兜底版本(性能殺手)

掌握 msubstr 原理與部署細節,能徹底解決 ThinkPHP 專案中中文截取亂碼與函數未定義的經典問題。

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