我试图从语言代码中获取语言名称,我运行
function test($local, $fallback)
{
$bundle = \ResourceBundle::create($local, 'ICUDATA-lang', $fallback);
if ($bundle === null) {
return "$local bundle not found";
}
$var = $bundle->get('Languages');
return $var->get('fr');
}
$locals = ['en', 'en_US', 'foo', 'en_AU', 'en_NZ'];
foreach ($locals as $local) {
var_dump(test($local, true));
}
echo PHP_EOL;
foreach ($locals as $local) {
var_dump(test($local, false));
}
string(6) "French"
string(6) "French"
NULL
NULL
NULL
string(6) "French"
string(22) "en_US bundle not found"
string(20) "foo bundle not found"
NULL
NULL
返回澳大利亚和新西兰的null
,表明国际错误为
无法加载资源元素'fr':U_MISSING_RESOURCE_ERROR“
\ResourceBundle::create
函数的第三个参数用于回调,这意味着它应该回退到其父语言环境。有趣的是parent locale of en_AU
是en_AU
。
是错误还是我错过了一些东西?
在en_001
的ICU数据目录中(请注意,您位于发布分支而非主分支上),既没有you listed on GitHub的文件,也没有en_US
的文件。在master分支上,您可以找到一个en_UK
文件,该文件似乎是正确的语言环境代码,而不是UK。
尽管我不能说为什么en_GB
不存在(就像您所做的那样,这是我绝对希望的),但看来,在所有测试中,结果都是“法语”加载正确的ICU路径,但是因为找不到该路径,所以已加载根路径。
您已经通过尝试en_US
证明了这一点。如果您尝试加载该数据目录中不存在的其他任何废话语言环境,则同样有效,en_foobar
和en_US
都一样(因为它们都不存在,如前所述)。
作为旁注:我认为您可能误解了fallback参数。这样一来,如果无法加载该语言,则将加载后备语言-而不是直接在父级上请求您请求的任何数据。
为了更清楚我在说什么,这里有一些例子。
使用无意义的语言环境进行加载始终会加载整个目录数据,因此您可以访问所有根数据:
en_UK
从en_NZ加载存在[[不存在的子语言:
$bundle = \ResourceBundle::create('stackoverflow-is-great', 'ICUDATA-lang', true);
var_dump($bundle->get('Languages')->get('fr')); // string(6) "French"
var_dump($bundle->get('Languages')->get('de')); // string(6) "German"
从en_NZ加载存在[[do的子语言:
$bundle = \ResourceBundle::create('en_NZ', 'ICUDATA-lang', true);
var_dump($bundle->get('Languages')->get('fr')); // NULL
var_dump($bundle->get('Languages')->get('de')); // NULL
概括地说:它实际上按预期工作,并在可用的地方提供数据,而在没有可用的地方则没有数据。
调试我是怎么发现的?基于PHP ResourceBundle文档页面上的
$bundle = \ResourceBundle::create('en_NZ', 'ICUDATA-lang', true); var_dump($bundle->get('Languages')->get('mi')); // string(6) "Māori"
。我添加了深度输出并具有非常方便的调试功能:this user comment
这会打印出一个(实际上很长,这就是为什么我不在这里添加它的)输出,它看起来像根数据。
最后一点:function t($rb, $depth = 0) { foreach($rb as $k => $v) { echo str_repeat('->', $depth); if(is_object($v)) { print_r($v); var_dump($k); t($v, ++$depth); } else { var_dump($k . " " . $v); } } } $rb = new ResourceBundle('en_UK', 'ICUDATA-lang', true); var_dump($rb->get('Languages')->get('fr')); t($rb);
似乎也是en_GB
,但我不确定效果如何。TL; DR:数据集中没有真正存在的前三个语言环境,因此加载了根数据,aliased to en_001 here和
en_NZ
像它们应该的那样工作。
en_AU
将永远不会受到加载有或没有
fallback的存储库的影响。
->get('Languages')->get($lang)
“ en”,“ en_AU和” en_NS“直接是$locals = ['en', 'en_US', 'foo', 'en_AU', 'en_NZ'];
:因此可以全部加载它们[[有或没有
'bas_il_ic'
后退。'bas'
的创建不会因ResourceBundle
而失败,但是,您可以从中得到的全部是fallback = true
s。NULL
参数只允许在fallback
时对ResourceBundle::create()
的parent是xx_YY
。它与xx
定义引起的inheritance无关,它不遵循上面定义的parent locale的原理,而是一种跨语言环境共享通用定义的方法。
因此,您得到的结果和文档都正确:后备为%%Parent{"xxxxxx"}
:'en':“法语”,因为存在语言环境“ en”,并且“法语”是true
的一部分>'en_US':“法语”,因为未定义语言环境“ en_US”,因此它落在“ en”上,并且“法语”是en.txt的一部分>
''foo':en.txt,因为语言环境“ foo”不存在,也不能回退。
NULL
,因为语言环境NULL
扩展了"en_AU" exists,但是它们都没有定义“ fr”。false
的一部分>''foo':“找不到foo束”:显然,“ foo”的确未定义。
true
时的解释相同。true
的ICU语言数据不继承xx_YY
之一?”这对所有语言环境均有效,不仅适用于基于英语的语言环境。