You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress分类列表中ÅÄÖ字符无法显示的PHP编码问题排查

解决WordPress瑞典语分类A-Z排序及ÅÄÖ显示问题

问题原因

  • 多字节字符截取错误:PHP原生字符串索引$cat->name[0]仅支持单字节字符,而Å、Ä、Ö属于UTF-8多字节字符(每个占2字节),直接取索引0会得到乱码的字节片段,导致$term_list的键名和$alphabet中的字符不匹配,无法正常读取对应分类。
  • 编码转换错误:utf8_decode会将UTF-8编码的字符转成ISO-8859-1,破坏ÅÄÖ的正确编码,导致它们被错误归类到Ã下,完全偏离预期。

解决方法

1. 修复首字符截取逻辑

使用PHP多字节扩展的mb_substr函数获取分类名称的首字符,确保拿到完整的UTF-8字符:

$first_letter = mb_substr($cat->name, 0, 1, 'UTF-8');

替换原代码中的$first_letter = $cat->name[0];,这样就能正确获取Å、Ä、Ö作为数组键名。

2. 统一UTF-8编码,移除utf8_decode

WordPress默认使用UTF-8编码(数据库、输出均为UTF-8),无需任何编码转换操作,直接使用原始字符即可。

3. 按瑞典语规则排序分类

默认orderby => 'name'是按ASCII排序,不会遵循瑞典语字母顺序(ÅÄÖ应排在Z之后),可以通过以下两种方式处理:

方式一:利用系统locale排序

// 获取分类前设置瑞典语locale
setlocale(LC_COLLATE, 'sv_SE.UTF-8');

$args = array(
    'taxonomy' => 'bryggeri',
    'orderby' => 'name',
    'order'  => 'ASC',
);

$cats = get_categories($args);

// 按瑞典语规则手动排序
usort($cats, function($a, $b) {
    return strcoll($a->name, $b->name);
});

注意:需确保服务器已安装瑞典语locale包,否则此方法无效。

方式二:手动字符映射排序

如果服务器未安装瑞典语locale,可通过字符映射实现排序:

usort($cats, function($a, $b) {
    // 将ÅÄÖ映射到Z之后的虚拟字符,保证排序顺序
    $map = array('Å' => 'ZAA', 'Ä' => 'ZAB', 'Ö' => 'ZAC');
    $a_name = strtr($a->name, $map);
    $b_name = strtr($b->name, $map);
    return strcmp($a_name, $b_name);
});

修正后的完整代码

<?php
// 设置瑞典语排序规则(可选,根据服务器情况选择)
setlocale(LC_COLLATE, 'sv_SE.UTF-8');

$alphabet = array("1","7","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","Å","Ä","Ö");

$args = array(
    'taxonomy' => 'bryggeri',
    'orderby' => 'name',
    'order'  => 'ASC',
);

$cats = get_categories($args);

// 按瑞典语规则排序分类
usort($cats, function($a, $b) {
    return strcoll($a->name, $b->name);
    // 若服务器无瑞典语locale,替换为下面的代码:
    // $map = array('Å' => 'ZAA', 'Ä' => 'ZAB', 'Ö' => 'ZAC');
    // $a_name = strtr($a->name, $map);
    // $b_name = strtr($b->name, $map);
    // return strcmp($a_name, $b_name);
});

$term_list = [];    
foreach ( $cats as $cat ){
    // 正确获取UTF-8首字符并转为大写(确保与$alphabet中的字符匹配)
    $first_letter = mb_substr($cat->name, 0, 1, 'UTF-8');
    $first_letter = mb_strtoupper($first_letter, 'UTF-8');
    $term_list[$first_letter][] = $cat;
}

unset($cat);
?>
<div class="tag-list">

<?php foreach ( $alphabet as $letter) :  ?>

    <div class="term-row" id="<?php echo $letter; ?>">
        <div class="term-letter">
            <h3><?php echo $letter;?></h3>
        </div>
        <div class="tag-items">

        <?php if (empty($term_list[$letter])): ?>

            <div class="tag-item">
            <p>-</p>
            </div>
        <?php else:

            foreach ( $term_list[$letter] as $term ): 
            $count = $term->count;
             ?>
            <div class="tag-item">
                <a href="<?php echo get_term_link( $term );?>"><?php echo $term->name;?></a> (<?php echo $count; ?>)
            </div>
            <?php endforeach;?>
        <?php endif; ?>
        </div>
    </div>
    <?php endforeach; ?>
    </div>

内容的提问来源于stack exchange,提问作者JLR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 00:15:32