A
A
Alexey Verkhovtsev2017-11-29 09:44:47
PHP
Alexey Verkhovtsev, 2017-11-29 09:44:47

Internationalization and localization in PHP, how to figure it out?

Hello. I decided to read about internationalization and localization on phprightway. In general, I do everything by example (it seems to me, rather), but nothing comes out and I am tormented by doubts about how I understand it.
Code from i18_setup.php example

<?php
error_reporting(E_ALL);
/**
 * 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', 'pt', 'es_ES', 'es', 'ru_Ru']);
}

//setting the source/default locale, for informational purposes
$lang = 'en_US';

if (isset($_GET['lang']) && valid($_GET['lang'])) {
  // 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
  $lang = $_COOKIE['lang'];
} elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
  $langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
  array_walk($langs, function (&$lang) { $lang = strtr(strtok($lang, ';'), ['-' => '_']); });
  foreach ($langs as $browser_lang) {
    if (valid($browser_lang)) {
      $lang = $browser_lang;
      break;
    }
  }
}

// here we define the global system locale given the found language
putenv("LANG=$lang");

// this might be useful for date functions (LC_TIME) or money formatting (LC_MONETARY), for instance
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');

// here we indicate the default domain the gettext() calls will respond to
textdomain('main');

// this would look for the string in forum.mo instead of main.mo
// echo dgettext('forum', 'Welcome back!');

the only thing here is added ru_Ru to the valid function array
This is the index
<?php include 'i18_setup.php'; ?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="header">
    <?php
    $name = 'Alexey';
    $unread = 1;
    ?>
    <h1><?php echo sprintf(gettext('Welcome, %s!'), $name); ?></h1>
    <?php if ($unread): ?>
      <h2>
        <?php
        echo sprintf(
          ngettext('Only one unread message',
              '%d unread messages',
              $unread),
          $unread
        );
        ?>
      </h2>
    <?php endif; ?>
  </div>
  <h1><?php echo gettext('Introduction'); ?></h1>
  <p><?php echo gettext('We\'re now translation some string'); ?></p>
</body>
</html>

Next, my folder structure is the
5a1e56a8ebd64214831469.png
folder localization.loc is the root, there is index.php. well, and accordingly, the test translation is made,
5a1e57203e97e242452212.png
I follow the link localization.loc/?lang=ru_Ru and I see the English. text. I understand that the problem is that I'm doing something wrong, please help or give me some more detailed article, because going to phprightway was not very clear to me.
Thanks in advance

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexander Kuznetsov, 2017-11-30
@DarkRaven

I would use something like symfony.com/doc/current/components/translation.html or https://docs.zendframework.com/zend-i18n/translation/ .

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question