Maison >développement back-end >tutoriel php >ThinkPHP+Smarty模板中截取包含中英文混同的字符串乱码的解决方案
ThinkPHP+Smarty模板中截取包含中英文混合的字符串乱码的解决方案
好几天没写博客了,其实有好多需要总结的,因为最近一直在忙着做项目,但是困惑了几天的Smarty模板中截取包含中英文混合的字符串乱码的问题,终于解决了,所以记录下来,需要的朋友看一下:
出现乱码的原因:
对于字符串的截取,truncate函数只适合英文用户,对与中文用户来说,使用 truncate会出现乱码,而且对于中文英文混合串来说,截取同样个数的字符串,实际显示长度上却不同,一个中文的长度大致相当于两个英文的长度。此外,truncate不能同时兼容GB2312、UTF-8等编码。
解决方法:自己写一个扩展类使用
ThinkPHP使用的smarty的truncate变量调节器所在的类文件位置:ThinkPHP\Library\Vendor\Smarty\plugins,其中有一个就是modifier.truncate.php,我们不用这个,我们自己写一个来实现
文件名:modifier.smartTruncate.php
<span style="color: #000000;">php</span><span style="color: #008000;">/*</span><span style="color: #008000;">* * 中英文多编码字符串截取</span><span style="color: #008000;">*/</span><span style="color: #0000ff;">function</span> smartDetectUTF8(<span style="color: #800080;">$string</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">static</span> <span style="color: #800080;">$result</span> = <span style="color: #0000ff;">array</span><span style="color: #000000;">(); </span><span style="color: #0000ff;">if</span>(! <span style="color: #008080;">array_key_exists</span>(<span style="color: #800080;">$key</span> = <span style="color: #008080;">md5</span>(<span style="color: #800080;">$string</span>), <span style="color: #800080;">$result</span><span style="color: #000000;">)) { </span><span style="color: #800080;">$utf8</span> = "<span style="color: #000000;"> /^(?: [\x09\x0A\x0D\x20-\x7E] # ASCII | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 )+$/xs </span>"<span style="color: #000000;">; </span><span style="color: #800080;">$result</span>[<span style="color: #800080;">$key</span>] = <span style="color: #008080;">preg_match</span>(<span style="color: #008080;">trim</span>(<span style="color: #800080;">$utf8</span>), <span style="color: #800080;">$string</span><span style="color: #000000;">); } </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$result</span>[<span style="color: #800080;">$key</span><span style="color: #000000;">];}</span><span style="color: #0000ff;">function</span> smartStrlen(<span style="color: #800080;">$string</span><span style="color: #000000;">){ </span><span style="color: #800080;">$result</span> = 0<span style="color: #000000;">; </span><span style="color: #800080;">$number</span> = smartDetectUTF8(<span style="color: #800080;">$string</span>) ? 3 : 2<span style="color: #000000;">; </span><span style="color: #0000ff;">for</span>(<span style="color: #800080;">$i</span> = 0; <span style="color: #800080;">$i</span> strlen(<span style="color: #800080;">$string</span>); <span style="color: #800080;">$i</span> += <span style="color: #800080;">$bytes</span><span style="color: #000000;">) { </span><span style="color: #800080;">$bytes</span> = <span style="color: #008080;">ord</span>(<span style="color: #008080;">substr</span>(<span style="color: #800080;">$string</span>, <span style="color: #800080;">$i</span>, 1)) > 127 ? <span style="color: #800080;">$number</span> : 1<span style="color: #000000;">; </span><span style="color: #800080;">$result</span> += <span style="color: #800080;">$bytes</span> > 1 ? 1.0 : 0.5<span style="color: #000000;">; } </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$result</span><span style="color: #000000;">;}</span><span style="color: #0000ff;">function</span> smartSubstr(<span style="color: #800080;">$string</span>, <span style="color: #800080;">$start</span>, <span style="color: #800080;">$length</span> = <span style="color: #0000ff;">null</span><span style="color: #000000;">){ </span><span style="color: #800080;">$result</span> = ''<span style="color: #000000;">; </span><span style="color: #800080;">$number</span> = smartDetectUTF8(<span style="color: #800080;">$string</span>) ? 3 : 2<span style="color: #000000;">; </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$start</span> ) { <span style="color: #800080;">$start</span> = <span style="color: #008080;">max</span>(smartStrlen(<span style="color: #800080;">$string</span>) + <span style="color: #800080;">$start</span>, 0<span style="color: #000000;">); } </span><span style="color: #0000ff;">for</span>(<span style="color: #800080;">$i</span> = 0; <span style="color: #800080;">$i</span> strlen(<span style="color: #800080;">$string</span>); <span style="color: #800080;">$i</span> += <span style="color: #800080;">$bytes</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$start</span> ) { <span style="color: #0000ff;">break</span><span style="color: #000000;">; } </span><span style="color: #800080;">$bytes</span> = <span style="color: #008080;">ord</span>(<span style="color: #008080;">substr</span>(<span style="color: #800080;">$string</span>, <span style="color: #800080;">$i</span>, 1)) > 127 ? <span style="color: #800080;">$number</span> : 1<span style="color: #000000;">; </span><span style="color: #800080;">$start</span> -= <span style="color: #800080;">$bytes</span> > 1 ? 1.0 : 0.5<span style="color: #000000;">; } </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">is_null</span>(<span style="color: #800080;">$length</span><span style="color: #000000;">)) { </span><span style="color: #800080;">$result</span> = <span style="color: #008080;">substr</span>(<span style="color: #800080;">$string</span>, <span style="color: #800080;">$i</span><span style="color: #000000;">); } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { </span><span style="color: #0000ff;">for</span>(<span style="color: #800080;">$j</span> = <span style="color: #800080;">$i</span>; <span style="color: #800080;">$j</span> strlen(<span style="color: #800080;">$string</span>); <span style="color: #800080;">$j</span> += <span style="color: #800080;">$bytes</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$length</span> ) { <span style="color: #0000ff;">break</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">if</span>((<span style="color: #800080;">$bytes</span> = <span style="color: #008080;">ord</span>(<span style="color: #008080;">substr</span>(<span style="color: #800080;">$string</span>, <span style="color: #800080;">$j</span>, 1)) > 127 ? <span style="color: #800080;">$number</span> : 1) > 1<span style="color: #000000;">) { </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$length</span> ) { <span style="color: #0000ff;">break</span><span style="color: #000000;">; } </span><span style="color: #800080;">$result</span> .= <span style="color: #008080;">substr</span>(<span style="color: #800080;">$string</span>, <span style="color: #800080;">$j</span>, <span style="color: #800080;">$bytes</span><span style="color: #000000;">); </span><span style="color: #800080;">$length</span> -= 1.0<span style="color: #000000;">; } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { </span><span style="color: #800080;">$result</span> .= <span style="color: #008080;">substr</span>(<span style="color: #800080;">$string</span>, <span style="color: #800080;">$j</span>, 1<span style="color: #000000;">); </span><span style="color: #800080;">$length</span> -= 0.5<span style="color: #000000;">; } } } </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$result</span><span style="color: #000000;">;}</span><span style="color: #0000ff;">function</span> smarty_modifier_smartTruncate(<span style="color: #800080;">$string</span>, <span style="color: #800080;">$length</span> = 80, <span style="color: #800080;">$etc</span> = '...',<span style="color: #800080;">$break_words</span> = <span style="color: #0000ff;">false</span>, <span style="color: #800080;">$middle</span> = <span style="color: #0000ff;">false</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">if</span> (<span style="color: #800080;">$length</span> == 0<span style="color: #000000;">) </span><span style="color: #0000ff;">return</span> ''<span style="color: #000000;">; </span><span style="color: #0000ff;">if</span> (smartStrlen(<span style="color: #800080;">$string</span>) > <span style="color: #800080;">$length</span><span style="color: #000000;">) { </span><span style="color: #800080;">$length</span> -= smartStrlen(<span style="color: #800080;">$etc</span><span style="color: #000000;">); </span><span style="color: #0000ff;">if</span> (!<span style="color: #800080;">$break_words</span> && !<span style="color: #800080;">$middle</span><span style="color: #000000;">) { </span><span style="color: #800080;">$string</span> = <span style="color: #008080;">preg_replace</span>('/\s+?(\S+)?$/', '', smartSubstr(<span style="color: #800080;">$string</span>, 0, <span style="color: #800080;">$length</span>+1<span style="color: #000000;">)); } </span><span style="color: #0000ff;">if</span>(!<span style="color: #800080;">$middle</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">return</span> smartSubstr(<span style="color: #800080;">$string</span>, 0, <span style="color: #800080;">$length</span>).<span style="color: #800080;">$etc</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { </span><span style="color: #0000ff;">return</span> smartSubstr(<span style="color: #800080;">$string</span>, 0, <span style="color: #800080;">$length</span>/2) . <span style="color: #800080;">$etc</span> . smartSubstr(<span style="color: #800080;">$string</span>, -<span style="color: #800080;">$length</span>/2<span style="color: #000000;">); } } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$string</span><span style="color: #000000;">; }}</span>?>
注意:在判断字符长度时,一个中文字符算1.0,一个英文字符算0.5,截取子字符串时不会出现参差不齐的情况.
使用方法:
{<span style="color: #800080;">$content</span>|smartTruncate:5:"..."}
ok,测试没有问题有问欢迎指出