PHP中使用substr()截取字符串出现中文乱码问题该怎么办


Posted in PHP onOctober 21, 2015

在PHP程序开发中,经常会执行字符串的截取操作,比如输出信息列表时,标题不宜过长,打印文章摘要时,也要执行一系列的字符串截取操作。遇到这些需求时,我们经常会想到使用substr()方法来实现,substr()对全英文字符串的截取是比较适合的。

但字符串只要出现中文字符,就有可能导致PHP substr中文乱码,因为中文UTF-8编码,每个汉字占3字节,而GB2312占2字节,英文占1字节,截取位数不准确,substr()硬生生地将一个中文字符“锯”成两半,造成断开的字符会把其后的..拉过来一起做一个字,所以出现了PHP substr中文乱码。

substr --- 取得部份字符串

语法 : string substr (string string, int start [, int length])

说明 :

substr( )传回 string的一部份字符串,由参数 start和 length指定。

如果 start是正数,传回的字符串将会从 string的第 start个字元开始。

Example :

<?php
$rest = substr ("abcdef", 1); // returns "bcdef"
$rest = substr ("abcdef", 1, 3); // returns "bcd"
?>

如果 start是负数,传回的字符串将会从 string结尾的第 start个字开始。

Example :

<?php
$rest = substr ("abcdef", -1); // returns "f"
$rest = substr ("abcdef", -2); // returns "ef"
$rest = substr ("abcdef", -3, 1); // returns "d"
?>

如果有给予参数 length而且是正数时,传回的字符串将会从 start传回 length个字元。
如果有给予参数 length而且是负数时,传回的字符串将会结束于 string结尾的第 length个字元。

Example :

<?php
$rest = substr ("abcdef", 1, -1); // returns "bcde"
?>

对于英文没有问题,我们测试一个中文

<?php
$rest = substr ("中国人", 1, -1); // returns "fdsafsda" 就是乱码了
?>

这种截取字符的结果,肯定不是我们想要的结果,这种出现PHP substr中文乱码的情况,可能会导致程序无法正常运行。解决办法主要有两种:

一、使用mbstring扩展库的mb_substr()截取就不会出现乱码了。

可以用mb_substr()/mb_strcut()这个函数,mb_substr()/mb_strcut()的用法与substr()相似,只是在mb_substr()/mb_strcut最后要加入多一个参数,以设定字符串的编码,但是一般的服务器都没打开php_mbstring.dll,需要在php.ini在把php_mbstring.dll打开。

<?php
  echo mb_substr("php中文字符encode",0,4,"utf-8");
?>

如果未指定最后一个编码参数,会是三个字节为一个中文,这就是utf-8编码的特点,若加上utf-8字符集说明,所以,是以一个字为单位来截取的。

使用的时候要注意php文件的编码,和网页显示时的编码。使用这个mb_substr方法要事先知道字符串的编码,如果不知道编码,就需要判断,mbstring库还提供了mb_check_encoding来检验字符串编码,但还不完善。

PHP 自带几种字符串截取函数,其中常用到的就是 substr 和 mb_substr。前者在处理中文时,GBK 为 2 个长度单位,UTF 为 3 个长度单位,后者指定编码后,一个中文即为 1 个长度单位。

substr 有时会截 1/3 个中文或半个中文,会显示乱码,相对来说 mb_substr 更适合我们使用。不过有时候 mb_substr 就显得不那么好用了。例如我要显示一个小图片的简要信息,5 个中文正好,超过 5 个就截取前4再加上 ”…”,这样处理中文是没问题了,可是处理英文或数字,这样截取就太短了。

二、自己书写截取函数,但效率不如用mbstring扩展库来得高。下面是ecshop里面的截取UTF-8编码下字符串的函数。

function sub_str($str, $length = , $append = true)
{
  $str = trim($str);
  $strlength = strlen($str);
  if ($length == || $length >= $strlength)
  {
    return $str; //截取长度等于或大于等于本字符串的长度,返回字符串本身
  }
  elseif ($length < ) //如果截取长度为负数
  {
    $length = $strlength + $length;//那么截取长度就等于字符串长度减去截取长度
    if ($length < )
    {
      $length = $strlength;//如果截取长度的绝对值大于字符串本身长度,则截取长度取字符串本身的长度
    }
  }
  if (function_exists('mb_substr'))
  {
    $newstr = mb_substr($str, , $length, EC_CHARSET);
  }
  elseif (function_exists('iconv_substr'))
  {
    $newstr = iconv_substr($str, , $length, EC_CHARSET);
  }
  else
  {
    //$newstr = trim_right(substr($str, , $length));
    $newstr = substr($str, , $length);
  }
  if ($append && $str != $newstr)
  {
    $newstr .= '...';
  }
  return $newstr;
}

好了,本文全部叙述到此为止,相信会给大家带来收获的,以上代码也很简单,有不明白的地方欢迎给我留言,我会在第一时间给大家答复的。

PHP 相关文章推荐
台湾中原大学php教程孙仲岳主讲
Jan 07 PHP
延长phpmyadmin登录时间的方法
Feb 06 PHP
php设计模式 Template (模板模式)
Jun 26 PHP
PHP数组操作汇总 php数组的使用技巧
Jul 17 PHP
php利用腾讯ip分享计划获取地理位置示例分享
Jan 20 PHP
PHP基于imap获取邮件实例
Nov 11 PHP
php操作mongoDB实例分析
Dec 29 PHP
php输出xml属性的方法
Mar 19 PHP
学习php设计模式 php实现模板方法模式
Dec 08 PHP
详解WordPress开发中的get_post与get_posts函数使用
Jan 04 PHP
PHP设计模式之工厂模式定义与用法详解
Apr 03 PHP
Laravel事件监听器用法实例分析
Mar 12 PHP
PHP中的switch语句的用法实例详解
Oct 21 #PHP
PHP 实现的将图片转换为TXT
Oct 21 #PHP
PHP实现清除wordpress里恶意代码
Oct 21 #PHP
表单提交错误后返回内容消失问题的解决方法(PHP网站)
Oct 20 #PHP
php的mail函数发送UTF-8编码中文邮件时标题乱码的解决办法
Oct 20 #PHP
PHP页面转UTF-8中文编码乱码的解决办法
Oct 20 #PHP
php限制文件下载速度的代码
Oct 20 #PHP
You might like
php截取字符串并保留完整xml标签的函数代码
2013/02/06 PHP
PHP调用存储过程返回值不一致问题的解决方法分析
2016/04/26 PHP
PHP 断点续传实例详解
2017/11/11 PHP
JQuery 国际象棋棋盘 实现代码
2009/06/26 Javascript
Js 弹出框口并返回值的两种常用方法
2010/12/30 Javascript
再谈javascript图片预加载技术(详细演示)
2011/03/12 Javascript
jQuery Masonry瀑布流插件使用详解
2014/11/17 Javascript
node.js中的buffer.Buffer.isEncoding方法使用说明
2014/12/14 Javascript
易被忽视的js事件问题总结
2016/05/14 Javascript
js实现登录验证码
2016/12/22 Javascript
jquery实现侧边栏左右伸缩效果的示例
2017/12/19 jQuery
JS实现常见的查找、排序、去重算法示例
2018/05/21 Javascript
用react-redux实现react组件之间数据共享的方法
2018/06/08 Javascript
Bootstrap fileinput 上传新文件移除时触发服务器同步删除的配置
2018/10/08 Javascript
node.js的Express服务器基本使用教程
2019/01/09 Javascript
layui问题之自动滚动二级iframe页面到指定位置的方法
2019/09/18 Javascript
解决layui的table插件无法多层级获取json数据的问题
2019/09/19 Javascript
如何搭建一个完整的Vue3.0+ts的项目步骤
2020/10/18 Javascript
[09:37]DOTA2卡尔工作室 英雄介绍圣堂刺客篇
2013/06/13 DOTA
[02:17]《辉夜杯》TRG战队巡礼
2015/10/26 DOTA
Python3多线程操作简单示例
2018/05/22 Python
pyqt5实现绘制ui,列表窗口,滚动窗口显示图片的方法
2019/06/20 Python
PyInstaller的安装和使用的详细步骤
2020/06/02 Python
英国领先的在线旅游和休闲零售商:lastminute.com
2019/01/23 全球购物
计算机专业个人简短的自我评价
2013/10/23 职场文书
生产部经理岗位职责
2013/12/16 职场文书
会计专业毕业生自荐信范文
2013/12/20 职场文书
医校毕业生自我鉴定
2014/01/25 职场文书
简历中自我评价怎么写
2014/02/12 职场文书
企业管理毕业生求职信范文
2014/03/07 职场文书
先进单位申报材料
2014/12/25 职场文书
2015年保险业务员工作总结
2015/05/27 职场文书
甲午风云观后感
2015/06/02 职场文书
2016秋季运动会前导词
2015/11/25 职场文书
初中信息技术教学反思
2016/02/16 职场文书
写作指导:怎么书写竞聘演讲稿?
2019/07/04 职场文书