【问题标题】:Sort an array with special characters in PHP在 PHP 中对具有特殊字符的数组进行排序
【发布时间】:2012-05-25 20:12:00
【问题描述】:

我有一个包含西班牙语语言名称的数组:

$lang["ko"] = "coreano"; //korean
$lang["ar"] = "árabe"; //arabic
$lang["es"] = "español"; //spanish
$lang["fr"] = "francés"; //french

我需要对数组进行排序并维护索引关联,因此我将 asort()SORT_LOCALE_STRING

一起使用
setlocale(LC_ALL,'es_ES.UTF-8'); //this is at the beginning (config file)
asort($lang,SORT_LOCALE_STRING);
print_r($lang);

预期的输出将按以下顺序排列:

  • 数组([ar] => árabe [ko] => coreano [es] => español [fr] => francés)

但是,这是我收到的:

  • 数组([ko] => coreano [es] => español [fr] => francés [ar] => árabe)

我错过了什么吗?感谢您的反馈意见! (我的服务器使用的是 PHP 版本 5.2.13)

【问题讨论】:

  • 大胆猜测:可能是因为c 出现在á 之前?
  • 这就是我使用 SORT_LOCALE_STRING 的原因。 'á' 应该出现在 'a' 之后和 'c' 之前。
  • 你检查setlocale的返回值了吗?很可能它只是失败了。
  • 是的,没关系。它适用于所有其他语言环境函数,如 strftime()。
  • @andufo:“没关系”是什么意思?另外,您使用的是什么操作系统?

标签: php setlocale asort


【解决方案1】:

尝试按音译名称排序:

function compareASCII($a, $b) {
    $at = iconv('UTF-8', 'ASCII//TRANSLIT', $a);
    $bt = iconv('UTF-8', 'ASCII//TRANSLIT', $b);
    return strcmp($at, $bt);
}

uasort($lang, 'compareASCII');

print_r($lang);

【讨论】:

  • 这可能适用于这种特定情况,但它不是一个强大的通用解决方案;如果您想对包含例如西里尔字母或希腊字母字符串的数组进行排序,会发生什么? ASCII 音译并不是特别可靠。
  • @WillVousden 你是对的。无论如何,我认为对于包含语言名称的数组来说没问题。
  • @lorenzo-s:Will 是对的,并且数组的内容不会进入其中(如果是希腊语语言的名称呢?)。该解决方案可能具有创造性,但在技术层面上存在根本缺陷。最好只解决问题,因为原始代码适用于其他人。
  • @lorenzo-s:可能没问题,但是如果后来决定语言的名称应该是语言本身(和相应的字母),例如韩语:한국의,那么可能有问题:)
  • @WillVousden 好点。事实上,同样的代码也应该适用于中文和希伯来语字符。
【解决方案2】:

您在 setlocale() 中错误地定义了您的语言环境。

变化:

setlocale(LC_ALL,'es_ES.UTF-8');

收件人:

setlocale(LC_ALL,'es_ES');

输出:

Array ( [ar] => árabe [ko] => coreano [es] => español [fr] => francés ) 

【讨论】:

  • 我也尝试过,但它返回相同的响应:Array ( [ko] => coreano [es] => español [fr] => francés [ar] => árabe )跨度>
  • 如果文件以 UTF-8 编码,则该区域设置是 100% 正确的。在任何情况下,语言环境后缀和文件编码都应该匹配。
  • @andufo 尝试在phptester.net 运行它,它对我来说很好。如果是这种情况,您应该看到 Jon 的评论并检查您的文件是如何编码的。
  • @GeorgeReith 你是对的。刚刚对其进行了测试,它在 phptester.net 中运行良好——关于它为什么不能在我的服务器上运行的任何想法?该文件采用 UTF-8 编码。
  • @andufo 太棒了,我建议您在测试服务器上运行echo mb_internal_encoding(); 以查看您的文件实际编码为什么。然后,您可以正确设置它,例如 mb_internal_encoding("UTF-8");,如果您的 apache 上的 apache 可能正在更改您的页面提供的编码,则您的 .htaccess
【解决方案3】:

setlocale 的文档提到

不同的系统有不同的语言环境命名方案。

您的系统可能无法将语言环境识别为es_ES。如果您使用的是 Windows,请尝试使用 esp_ESP

【讨论】:

    【解决方案4】:

    试试这个

    setlocale(LC_COLLATE, 'nl_BE.utf8');
    $array = array('coreano','árabe','español','francés');
    usort($array, 'strcoll'); 
    print_r($array);
    

    【讨论】:

      【解决方案5】:

      这不是问题!

      您的初始解决方案完全符合预期, 您的问题是 setlocale 函数未能设置语言环境,因此 asort($array, SORT_LOCALE_STRING) 无法按预期排序

      您可以在phptester.net 尝试自己的代码,该代码确实接受 setlocale():

      $lang["ko"] = "coreano"; //korean
      $lang["ar"] = "árabe"; //arabic
      $lang["es"] = "español"; //spanish
      $lang["fr"] = "francés"; //french
      
      asort($lang,SORT_LOCALE_STRING);
      echo "<pre>";
      print_r($lang);
      echo "</pre>";
      
      echo "<pre>";
      /*this should return es_ES; 
      if returns false it has failed and asort wont return expected order
      */
      var_dump(setlocale(LC_ALL,'es_ES')); 
      echo "</pre>";
      
      asort($lang,SORT_LOCALE_STRING);
      echo "<pre>";
      print_r($lang);
      

      【讨论】:

        猜你喜欢
        • 2011-02-23
        • 2014-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-05
        相关资源
        最近更新 更多