首頁 >php教程 >php手册 >ThinkPHP+Smarty模板中截取包含中英文混合的字符串乱码的解决方案 - Steven*

ThinkPHP+Smarty模板中截取包含中英文混合的字符串乱码的解决方案 - Steven*

WBOY
WBOY原創
2016-05-20 11:40:47973瀏覽

好几天没写博客了,其实有好多需要总结的,因为最近一直在忙着做项目,但是困惑了几天的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,测试没有问题有问欢迎指出

 

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn