Gettext - PHP - WSL Ubuntu 系统中的语言环境具有完整的代码,而浏览器具有较短的代码
Gettext - PHP - Locales in WSL Ubuntu system have complete codes while browser has short ones
我正在向我的网站添加本地化功能。
我正在根据以下模板从头开始创建该网站:
https://www.w3schools.com/Css/css_rwd_templates.asp
这是一个没有本地化的简单模板。
相反,我将拥有一个管理本地化、cookie、语言更改等的网站。
我读了这个教程:
https://www.toptal.com/php/build-multilingual-app-with-gettext
并且
https://blog.terresquall.com/2020/09/debugging-php-gettext/
和其他页面。
现在我正在使用带有 WSL Ubuntu 系统的 Windows10 机器。
本地化代码有效,我在 HTML 页面的某个地方测试了 gettext 函数,安装了所有测试语言环境。
我正在使用教程中的代码并进行一些编辑:
<?php
echo phpversion();
if ( false === function_exists('gettext') ) {
echo "You do not have the gettext library installed with PHP.";
exit(1);
} else {echo "OK gettext";}
/**
* Verifies if the given $locale is supported in the project
* @param string $locale
* @return bool
*/
function valid($locale) {
return in_array($locale, ['en_US', 'en', 'pt_BR', 'it','es']);
}
//setting the source/default locale, for informational purposes
if (isset($_GET['lang']) && valid($_GET['lang'])) {
// the locale can be changed through the query-string
printf('the locale can be changed through the query-string - ');
$lang = $_GET['lang']; //you should sanitize this!
setcookie('lang', $lang); //it's stored in a cookie so it can be reused
} elseif (isset($_COOKIE['lang']) && valid($_COOKIE['lang'])) {
// if the cookie is present instead, let's just keep it
printf(' if the cookie is present instead, let\'s just keep it - ');
$lang = $_COOKIE['lang']; //you should sanitize this!
} elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
// default: look for the languages the browser says the user accepts
printf('default: look for the languages the browser says the user accepts - ');
$langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
array_walk($langs, function (&$lang) { $lang = strtr(strtok($lang, ';'), ['-' => '_']); });
foreach ($langs as $browser_lang) {
printf('LANGUAGE ACCEPTED=');
printf($browser_lang);
if (valid($browser_lang)) {
$lang = $browser_lang;
break;
}
}
}
//manually coded for testing purposes
$lang ="en_US.utf8"; //this works, while not setting it I get two-char language code like "it"
// here we define the global system locale given the found language
putenv("LANG=$lang");
printf("LANG=".$lang);
// this might be useful for date functions (LC_TIME) or money formatting (LC_MONETARY), for instance
$currentLocale = setlocale(LC_ALL, $lang);
// this will make Gettext look for ../locales/<lang>/LC_MESSAGES/main.mo
bindtextdomain('main', './locales');
// indicates in what encoding the file should be read
bind_textdomain_codeset('main', 'UTF-8');
// if your application has additional domains, as cited before, you should bind them here as well
//bindtextdomain('forum', '../locales');
//bind_textdomain_codeset('forum', 'UTF-8');
//$currentLocale = setlocale(LC_ALL, 0);
echo $LANG
//echo "Current Locale=".$currentLocale;
?>
但是
我意识到来自浏览器的计算语言可以采用“it”、“en”、“es”这样的形式,因为浏览器设置允许使用它(以及更具体的 languages/locales,如 en_US ),
Ubuntu 系统上的语言环境只有完整的语言代码,例如 en_US.utf8.
我还必须添加 .utf8 后缀,因为 Ubuntu 有那些语言环境但是
这当然只适用于支持 UTF-8 的语言。这是可能出现未翻译字符串的进一步原因。
我计划使用 key/values 对而不是默认的英语未翻译字符串。
如果我手动输入该值,则会发生翻译,而如果 $LANG 为“en”或浏览器设置了语言,我会得到未翻译的字符串。我在 Windows10 系统上用一些不同的浏览器测试了它。
我的想法是简单的语言是默认的,比如“en”、“es”、“it”,但这些“通用”语言似乎不作为语言环境出现。
如何从浏览器管理语言环境以使代码始终有效?
我想我只需要管理网站将支持的语言和区域设置,
注意处理必要的字符串,根据服务器列表中有效可用的区域设置标识符。
使用一些 'if' 条件足以创建正确的字符串,即使对于像 en、es、it 这样的通用语言也是如此。
只需要一些字符串连接。
示例:如果我想要通用英语语言支持,我会检查语言变量的前两个字母。
如果以'en'开头我选择en_GB.utf8
这只是最简单的情况。可以进行更精细的区域设置。
代码示例:
$lang_prefix=substr( $lang, 0, 2 );
switch ($lang_prefix)
{
case 'en': $lang="en_GB.utf8";break;
case 'it': $lang="it_IT.utf8";break;
default: $lang="en_GB.utf8";
}
我正在向我的网站添加本地化功能。 我正在根据以下模板从头开始创建该网站: https://www.w3schools.com/Css/css_rwd_templates.asp
这是一个没有本地化的简单模板。 相反,我将拥有一个管理本地化、cookie、语言更改等的网站。
我读了这个教程: https://www.toptal.com/php/build-multilingual-app-with-gettext 并且 https://blog.terresquall.com/2020/09/debugging-php-gettext/ 和其他页面。
现在我正在使用带有 WSL Ubuntu 系统的 Windows10 机器。 本地化代码有效,我在 HTML 页面的某个地方测试了 gettext 函数,安装了所有测试语言环境。
我正在使用教程中的代码并进行一些编辑:
<?php
echo phpversion();
if ( false === function_exists('gettext') ) {
echo "You do not have the gettext library installed with PHP.";
exit(1);
} else {echo "OK gettext";}
/**
* Verifies if the given $locale is supported in the project
* @param string $locale
* @return bool
*/
function valid($locale) {
return in_array($locale, ['en_US', 'en', 'pt_BR', 'it','es']);
}
//setting the source/default locale, for informational purposes
if (isset($_GET['lang']) && valid($_GET['lang'])) {
// the locale can be changed through the query-string
printf('the locale can be changed through the query-string - ');
$lang = $_GET['lang']; //you should sanitize this!
setcookie('lang', $lang); //it's stored in a cookie so it can be reused
} elseif (isset($_COOKIE['lang']) && valid($_COOKIE['lang'])) {
// if the cookie is present instead, let's just keep it
printf(' if the cookie is present instead, let\'s just keep it - ');
$lang = $_COOKIE['lang']; //you should sanitize this!
} elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
// default: look for the languages the browser says the user accepts
printf('default: look for the languages the browser says the user accepts - ');
$langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
array_walk($langs, function (&$lang) { $lang = strtr(strtok($lang, ';'), ['-' => '_']); });
foreach ($langs as $browser_lang) {
printf('LANGUAGE ACCEPTED=');
printf($browser_lang);
if (valid($browser_lang)) {
$lang = $browser_lang;
break;
}
}
}
//manually coded for testing purposes
$lang ="en_US.utf8"; //this works, while not setting it I get two-char language code like "it"
// here we define the global system locale given the found language
putenv("LANG=$lang");
printf("LANG=".$lang);
// this might be useful for date functions (LC_TIME) or money formatting (LC_MONETARY), for instance
$currentLocale = setlocale(LC_ALL, $lang);
// this will make Gettext look for ../locales/<lang>/LC_MESSAGES/main.mo
bindtextdomain('main', './locales');
// indicates in what encoding the file should be read
bind_textdomain_codeset('main', 'UTF-8');
// if your application has additional domains, as cited before, you should bind them here as well
//bindtextdomain('forum', '../locales');
//bind_textdomain_codeset('forum', 'UTF-8');
//$currentLocale = setlocale(LC_ALL, 0);
echo $LANG
//echo "Current Locale=".$currentLocale;
?>
但是 我意识到来自浏览器的计算语言可以采用“it”、“en”、“es”这样的形式,因为浏览器设置允许使用它(以及更具体的 languages/locales,如 en_US ), Ubuntu 系统上的语言环境只有完整的语言代码,例如 en_US.utf8.
我还必须添加 .utf8 后缀,因为 Ubuntu 有那些语言环境但是 这当然只适用于支持 UTF-8 的语言。这是可能出现未翻译字符串的进一步原因。
我计划使用 key/values 对而不是默认的英语未翻译字符串。
如果我手动输入该值,则会发生翻译,而如果 $LANG 为“en”或浏览器设置了语言,我会得到未翻译的字符串。我在 Windows10 系统上用一些不同的浏览器测试了它。
我的想法是简单的语言是默认的,比如“en”、“es”、“it”,但这些“通用”语言似乎不作为语言环境出现。
如何从浏览器管理语言环境以使代码始终有效?
我想我只需要管理网站将支持的语言和区域设置,
注意处理必要的字符串,根据服务器列表中有效可用的区域设置标识符。
使用一些 'if' 条件足以创建正确的字符串,即使对于像 en、es、it 这样的通用语言也是如此。
只需要一些字符串连接。
示例:如果我想要通用英语语言支持,我会检查语言变量的前两个字母。
如果以'en'开头我选择en_GB.utf8
这只是最简单的情况。可以进行更精细的区域设置。
代码示例:
$lang_prefix=substr( $lang, 0, 2 );
switch ($lang_prefix)
{
case 'en': $lang="en_GB.utf8";break;
case 'it': $lang="it_IT.utf8";break;
default: $lang="en_GB.utf8";
}