Перевод веб-сайта на язык PHP (SQL) - PullRequest
0 голосов
/ 09 июля 2020

Я хочу реализовать на своем веб-сайте языковой перевод. Для этого в моей базе данных создается таблица «переводы»:

id | de    | en    | other languages    
1  | Hallo | Hello | ...

На основании этого я добавил в свой заголовок следующий запрос:

 if ($user['language'] == 'de') {
        // Select prepared PDO 
        $statement = $pdo->prepare("SELECT id, de FROM translations");
        $result = $statement->execute(array());
        $text = $statement->fetch();
    }

if .... other languages

Я хочу показать текст перевод на основе языка пользователя. Мне интересно, есть ли простой метод эха php, который я могу использовать сейчас. Как объяснялось выше, у меня есть перевод в таблице, но какой способ повторить его проще всего?

Например. Текущее состояние:

<h4 class="...">Hallo</h4>

Новое состояние с переводом (конечно, не работает):

<h4 class="..."><?php echo $text['en'] ?></h4>

Так что мне не хватает простого метода адресации идентификатора (строки) для этот текстовый вывод, который в этом примере равен «1».

В качестве возможного метода я нашел этот пример:

<?php
$age=array("Peter"=>"35");
echo "Peter is " . $age['Peter'] . " years old.";
?>

Я думаю, что могу использовать это, и он выглядит по размеру текста как эффективный . Но я не уверен, как изменить запрос для моей таблицы выше. Лучше всего я могу сделать что-нибудь вроде:

echo $text['1']

, и он показывает текстовый вывод: « Hallo ». И в случае:

echo $text['2']

будет показано « Hello ».

Что вы думаете об этом методе? И не могли бы вы помочь мне изменить мой запрос, чтобы этот метод работал?

Большое спасибо!

Ответы [ 3 ]

1 голос
/ 10 июля 2020

Основываясь на ваших вопросах в моем первом ответе, я решил добавить другое решение - проще без функций et c.

Получить все переводы одним запросом с помощью fetchAll:

$statement = $pdo->prepare("SELECT id, de, en FROM translations");
$result = $statement->execute();
$textsRaw = $statement->fetchAll();

Ваш $textsRaw будет выглядеть так:

$textsRaw = [ 
  ['id' => 1, 'de' => 'Hallo', 'en' => 'Hello'],
  ['id' => 2, 'de' => 'auf Wiederschauen', 'en' => 'Good bye'],
];

Теперь мы преобразуем $textsRaw в $texts с более простой структурой:

$texts = [];
foreach ($textsRaw as $text) {
  $texts[$text['id']] = $text[$user['language']];
}

Теперь $texts выглядит так:

$texts = [1 => 'Hello', '2' => 'Good bye'];

Если у вас есть это, то перевод так же просто, как и сделать:

echo $texts[1];
echo $texts[2];

Если вы получите доступ к идентификатору перевода, который не существует, вы получите обычное php уведомление: PHP Notice: Undefined offset: 3 in ....php on line ...

1 голос
/ 10 июля 2020

Однажды я решил это вот так, я не хотел выбирать все данные, так как думал, что это будет пустой тратой ресурсов. Решение, которое я придумал, было (IMO) довольно элегантным:

Имейте переменную языка в нем, например $language = 'NL'. Затем используйте в select:

SELECT description_{$language} as description FROM example

Если вы его получите, вы можете просто использовать $result['description'] на желаемом языке:)

Это требует минимальных усилий для ваших запросов. Вы можете создать функцию с ['title', 'description'] в качестве входных данных, которая возвращает ее в том формате, в котором он находится в запросе, таким образом вы сохраняете ваши запросы немного меньше:

function langCols($columns){
    $lang = 'NL'; // implement your language logic here
    $transColumns = array_map(function(string $column){
        return $column .'_'.$lang.' AS '.$column;
    }, $columns);
    
    return implode(', ', $transColumns);
}

Обратите внимание, что это было решение в моем случае, но с минимальными усилиями он должен соответствовать вашим потребностям

0 голосов
/ 09 июля 2020

Получить все переводы в одном запросе с помощью fetchAll:

$statement = $pdo->prepare("SELECT id, de, en FROM translations");
$result = $statement->execute();
$texts = $statement->fetchAll();

Ваш $texts будет выглядеть так:

$texts = [ 
  ['id' => 1, 'de' => 'Hallo', 'en' => 'Hello'],
  ['id' => 2, 'de' => 'auf Wiederschauen', 'en' => 'Good bye'],
];

Теперь вы не можете сделать это с помощью простой конструкции эха, но вы можете определить функцию следующим образом:

function t(int $key): string {
  global $texts;
  global $user;

  $translationTexts = array_filter($texts, function(array $text) use ($key, $user) { return $text['id'] === $key; });

  if (count($translationTexts) !== 1) {
    throw new Exception('Unknown text key: '.$key);
  }

  return reset($translationTexts)[$user['language']];
}

Теперь, куда бы вы ни хотели перевести, просто введите: echo t(1); или echo t(2);, и в зависимости от языка пользователя он будет выводить перевод, например:

$user = ['language' => 'en'];

echo t(1);
echo t(2);

$user = ['language' => 'de'];

echo t(1);
echo t(2);

И вывод:

Hello
Good bye
Hallo
auf Wiederschauen

И если вы используете какой-либо несуществующий идентификатор перевода, например t(3);, вы получите исключение: PHP Fatal error: Uncaught Exception: Unknown text key: 3

Лучше бы иметь переводчик service / class, но я думаю, что эта простая версия лучше для начинающих.

Также вы можете подумать об использовании одного из языков в качестве ключа перевода (или даже ввести новый столбец в качестве ключа перевода), чтобы он был более описательным : echo t('hello') - это легче отследить в исходном коде, чем echo t(1).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...