- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章比较discuz和ecshop的截取字符串函数php版由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
下面先给出两个版本函数的源代码以及简单测试,最后我会给出一个实用性更强的字符串截取函数。需要注意的是:这里讨论的字符串截取问题都是针对UTF-8编码的中文字符串。 discuz版本 。
复制代码代码如下
/** * [discuz] 基于PHP没有安装 mb_substr 等扩展截取字符串,如果截取中文字则按2个字符计算 * @param $string 要截取的字符串 * @param $length 要截取的字符数 * @param $dot 替换截掉部分的结尾字符串 * @return 返回截取后的字符串 */ function cutstr($string, $length, $dot = '...') { // 如果字符串小于要截取的长度则直接返回 // 此处使用strlen获取字符串长度有很大的弊病,比如对字符串“新年快乐”要截取4个中文字符, // 那么必须知道这4个中文字符的字节数,否则返回的字符串可能会是“新年快乐...” if (strlen($string) <= $length) { return $string; } // 转换原字符串中htmlspecialchars $pre = chr(1); $end = chr(1); $string = str_replace ( array ('&', '"', '<', '>' ), array ($pre . '&' . $end, $pre . '"' . $end, $pre . '<' . $end, $pre . '>' . $end ), $string ); $strcut = ''; // 初始化返回值 // 如果是utf-8编码(这个判断有点不全,有可能是utf8) if (strtolower ( CHARSET ) == 'utf-8') { // 初始连续循环指针$n,最后一个字位数$tn,截取的字符数$noc $n = $tn = $noc = 0; while ( $n < strlen ( $string ) ) { $t = ord ( $string [$n] ); if ($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) { // 如果是英语半角符号等,$n指针后移1位,$tn最后字是1位 $tn = 1; $n++; $noc++; } elseif (194 <= $t && $t <= 223) { // 如果是二字节字符$n指针后移2位,$tn最后字是2位 $tn = 2; $n += 2; $noc += 2; } elseif (224 <= $t && $t <= 239) { // 如果是三字节(可以理解为中字词),$n后移3位,$tn最后字是3位 $tn = 3; $n += 3; $noc += 2; } elseif (240 <= $t && $t <= 247) { $tn = 4; $n += 4; $noc += 2; } elseif (248 <= $t && $t <= 251) { $tn = 5; $n += 5; $noc += 2; } elseif ($t == 252 || $t == 253) { $tn = 6; $n += 6; $noc += 2; } else { $n++; } // 超过了要取的数就跳出连续循环 if ($noc >= $length) { break; } } // 这个地方是把最后一个字去掉,以备加$dot if ($noc > $length) { $n -= $tn; } $strcut = substr ( $string, 0, $n ); } else { // 并非utf-8编码的全角就后移2位 for ($i = 0; $i < $length; $i ++) { $strcut .= ord ( $string [$i] ) > 127 ? $string [$i] . $string [++ $i] : $string [$i]; } } // 再还原最初的htmlspecialchars $strcut = str_replace( array ($pre . '&' . $end, $pre . '"' . $end, $pre . '<' . $end, $pre . '>' . $end ), array ('&', '"', '<', '>' ), $strcut ); $pos = strrpos ( $strcut, chr ( 1 ) ); if ($pos !== false) { $strcut = substr ( $strcut, 0, $pos ); } return $strcut . $dot; // 最后把截取加上$dot输出 } 。
discuz版本的最大缺陷在于使用 strlen 获取原始字符串的长度,并用来和传入的要截取长度参数(字节数)进行比较,由于UTF-8的中文字符的字节数是不固定的,所以就会面临这样的窘境:如果要截取4个中文字符应该指定多大的截取长度呢?8字节还是12字节呢?。。。这是无法预计的,也正是因为这个问题discuz的cutstr实际是有bug的,通过下面的测试结果能看出: 。
复制代码代码如下
$str1 = "欲穷千里目"; echo my_cutstr($str1, 10, "...")."\n"; // 输出:欲穷千里目... [这是一个bug,想想是什么原因导致?] echo my_cutstr($str1, 15, "...")."\n"; // 输出:欲穷千里目 。
导致上述bug的原因在与cutstr函数在截取字符的时候是将一个中文字按2个字符算,那么5个中文字就是10字符,而原始字符串的长度是15字节,所以cutstr认为“成功地”从15字符的串上截取了10个字符,然后加上了“尾巴”。要解决这个bug只要在判断一下返回的子串是否和原始串相同,如果相同就不加“尾巴”。 ecshop版 。
复制代码代码如下
/** * [ecshop] 基于PHP的 mb_substr,iconv_substr 这两个扩展来截取字符串,中文字符都是按1个字符长度计算; * 该函数仅适用于utf-8编码的中文字符串。 * * @param $str 原始字符串 * @param $length 截取的字符数 * @param $append 替换截掉部分的结尾字符串 * @return 返回截取后的字符串 */ function sub_str($str, $length = 0, $append = '...') { $str = trim($str); $strlength = strlen($str); if ($length == 0 || $length >= $strlength) { return $str; } elseif ($length < 0) { $length = $strlength + $length; if ($length < 0) { $length = $strlength; } } if ( function_exists('mb_substr') ) { $newstr = mb_substr($str, 0, $length, 'utf-8'); } elseif ( function_exists('iconv_substr') ) { $newstr = iconv_substr($str, 0, $length, 'utf-8'); } else { //$newstr = trim_right(substr($str, 0, $length)); $newstr = substr($str, 0, $length); } if ($append && $str != $newstr) { $newstr .= $append; } return $newstr; } 。
ecshop版的特点和缺点都在于将中文字符算作一个字符,如果原始字符串中不含中文,比如:abcd1234,如果本意是要截取4个中文字符或者8个英文字符,那么使用ecshop的版本就得不到期望的结果,返回值的是:abcd。下面是简单的测试结果: 。
复制代码代码如下
$str1 = "白日依山尽,黄河入海流"; echo $str1."\n"; echo my_sub_str($str1, 4, "...")."\n"; // 输出:白日依山... $str2 = "白1日2依3山4"; echo $str2."\n"; echo my_sub_str($str2, 4, "...")."\n"; // 输出:白1日2... 。
优化版 截取中文字符串的大部分应用场景是“原始字符串可以是中文、英文、数字混杂的,中文字按2个字符算,英文数字按1个字符算”,针对这个需求下面给出一个实现版本: 。
复制代码代码如下
/** * 字符串截取,中文字符按2个字符计算,同时支持GBK和UTF-8编码 * @param $string 要截取的字符串 * @param $length 要截取的字符数 * @param $append 添加到子串后的尾巴 * @return 返回截取后的字符串 */ function substring($string, $length, $append = false) { if ( $length <= 0 ) { return ''; } // 检测原始字符串是否为UTF-8编码 $is_utf8 = false; $str1 = @iconv("UTF-8", "GBK", $string); $str2 = @iconv("GBK", "UTF-8", $str1); if ( $string == $str2 ) { $is_utf8 = true; // 如果是UTF-8编码,则使用GBK编码的 $string = $str1; } $newstr = ''; for ($i = 0; $i < $length; $i ++) { $newstr .= ord ($string[$i]) > 127 ? $string[$i] . $string[++$i] : $string[$i]; } if ( $is_utf8 ) { $newstr = @iconv("GBK", "UTF-8", $newstr); } if ($append && $newstr != $string) { $newstr .= $append; } return $newstr; } 。
测试结果见下(GBK和UTF-8的结果一致): 。
复制代码代码如下
$str1 = "白日依山尽,黄河入海流"; echo substring($str1, 4, "...")."\n"; // 输出:白日... echo substring($str1, 5, "...")."\n"; // 输出:白日依... $str2 = "12白34日56依78山"; echo substring($str2, 4, "...")."\n"; // 输出:12白... echo substring($str2, 5, "...")."\n"; // 输出:12白3... 。
作者:edwardlost' blog 。
最后此篇关于比较discuz和ecshop的截取字符串函数php版的文章就讲到这里了,如果你想了解更多关于比较discuz和ecshop的截取字符串函数php版的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
1、添加菜单项 打开 /admin/includes/inc_menu.php文件(后台框架左边菜单),在最
下面是实现批量上传(加入自定义属性)思路以及实现的过程。 1.加入属性 之所以只能上传特定的属性,应该是批量上传的固定属性都来自于一张表。esc_goods表.
php\new\pdzy\admin\includes\inc_menu.php 添加 $modules['02_cat_and_goods']['zijidingyi_de
首先声明个人观点:不建议大家去除别人的版权,请尊重知识产权,特别是这样好的系统。 去版权这个事是我做的最多的估计,因为每次去用cms系统做网站时,第一件做的事情就是去版权。一般的方法就是在edit
修改了install/includes/lib_installer.php的411或者412行,记住路径一定要正确 include(ROOT_PATH . 'install/languages/'
在user.php 的注册成功信息显示前面,大概是 show_message(sprintf($_LANG['register_success'].............前面加入 注意
在 PHP7 上安装 ECShop V2.7.3时,报错! Deprecated: Methods with the same name as their class will not be co
2.72版本之后修改后台登录地址非常方便,步骤如下: 1、修改 admin 文件夹名称为别人猜不到的,例如 ecshop 2、打开data/config.php文件 查找:
研读过ucenter 的原理后,再结合测试 ucenter + modoer + discuz X 1.5 + ecshop 2.7.2 实现了完美的同步登入和退出 发现一个简单的方法就是,把uc
某客户的ecshop后台登陆后,显示成功,但是自动退出到登陆界面。 问题解决: 因为 windows 系统不区分目录大小写,而php是区分大小写的 那么 http
由于很多用户需要加上商品自定义吃寻大小等 如图 首先在\admin\templates\goods_info.htm里面找到 属性与规格 的位置 发现他调用了{$goods_attr_html
网页底部版权 找到js/common.js 删除以下js代码即可 复制代码 代码如下: onload = function()
前台部分: 1:去掉头部TITLE部分的ECSHOP演示站 Powered by ecshop 前者在后台商店设置 - 商店标题修改 后者打开includes/
ECSHOP出现 XMlHttpRequest status:[500] Unknow status 这个错误 把/admin/templates/top.htm 这个文件中{insert_scr
我是一名优秀的程序员,十分优秀!