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> < <span style="color: #008080">strlen</span>(<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> < 0<span style="color: #000000">) { </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> < <span style="color: #008080">strlen</span>(<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> <= 0<span style="color: #000000">) { </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> < <span style="color: #008080">strlen</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: #0000ff">if</span>(<span style="color: #800080">$length</span> <= 0<span style="color: #000000">) { </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> < 1.0<span style="color: #000000">) { </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 style="color:transparent">/本文来源gaodai#ma#com搞*!代#%^码网%</span><sub>搞代gaodaima码</sub>{ </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,测试没有问题有问欢迎指出