【问题标题】:PHP get multilanguage data from database with instant variablesPHP使用实例变量从数据库中获取多语言数据
【发布时间】:2018-10-24 09:27:09
【问题描述】:

我想要的是将每个单词/句子/ ...存储在数据库表中,如下所示:

表名:

translate

列:

id, var, dutch, english, french

例子:

'1', 'titleOne', 'Hallo Wereld!', 'Hello World!', 'Bonjour le monde!'

我想要在标题部分打印变量:

<?php
echo $titleOne;
?>

由于会有数百行我不想为每一行设置$titleOne = $row['titleOne']

有人可以帮我做一个很好的查询、拉取、获取、数组、循环……不管你怎么称呼它? (或者一个不错的替代方式也不错!)

这是纯 PHP,没有使用任何框架。

PS:我根本不是 PHP 专家,所以请尽量保持简单:-)!

非常感谢!

【问题讨论】:

  • 你在使用任何框架吗?或者在核心 PHP 中编码?
  • 什么包含一个典型的$row 数组?
  • 您对使用翻译键有正确的想法,但不要为每种语言使用单个列。您不希望每次添加/删除语言时都必须修改表结构。有很多方法可以实现多语言站点。这是我用于中小型网站的一种简单方法 - stackoverflow.com/a/49758067/296555。如果您想要 i18n 的更多功能,请查看框架中的包 - Symfony 的很好 symfony.com/doc/current/best_practices/i18n.html
  • 呼应@waterloomatt 现在停止使用您正在使用的设计,并在此Translate 表上退后一步。至少应该是id | var | language | translation。条目看起来像1 | 'titleOne' | 'english' | 'Hello World'。然后,当您查询它时,您执行SELECT var, translation FROM translate WHERE language = 'english'; 现在您可以将查询参数化到该表以获取一种语言,而不是切换代码中的列,这将使您免于潜在的 sql 注入向量,并使您的应用程序可以扩展而无需不断更改数据库架构。
  • @KevinGoethals - 您可以但不应该将变量直接嵌入到您的 SQL 语句中(SQL 注入攻击)。相反,您应该使用准备好的语句将变量绑定到查询中。但是,准备好的语句不支持也不应该将列名作为占位符。在这里查看更多信息 - stackoverflow.com/q/182287/296555。理解这一点并使用效果良好的设计是设计师的工作。这些限制是有原因的。听起来您已经准备好深入研究 SQL 查询了。从 PDO 开始 - phpdelusions.net/pdo

标签: php mysql sql multilingual


【解决方案1】:

直接回答您的问题。您可以按如下方式查询当前设置:

-- For Dutch (pseudocode)
$query = 'SELECT var, dutch FROM translate';

$translations = array();   
while loop ($row = $query) {
    $translations['var'] = $row['dutch'];
}

// Then, to access translations you would:
echo $translations['titleOne'];

但是你不想这样做。这种表格结构会带你走上遗憾的道路。注意我们的警告。有很多方法可以解决这个问题,而您选择走 SQL 路线,所以这里有一些提示。

更改您的表格结构,这样您就不必在每次添加新语言时都添加新列。

表格:语言(添加新行以支持新语言)

id, locale, language

1, en_CA, English
2, en_US, English
3, en_UK, English
4, es_ES, Spanish
5, es_MX, Spanish
...

表格:翻译(添加新行添加翻译)

id, locale, translation_key, translation

1, en_CA, 'hello', 'Hi from Canada'
2, en_US, 'hello', 'Hi from the US'
3, en_UK, 'hello', 'Hi from the UK'
4, es_ES, 'hello', 'Hi from Spain'
5, es_MX, 'hello', 'Hi from Mexico'
...

translations.locale 应该是指向语言的外键,但我不确定你的 SQL 级别是什么,所以我知道如何让它尽可能清晰。

我假设您可以弄清楚如何从 PHP 查询您的数据库。你想做的是:

  • 确定要使用的语言环境。这将是最棘手的部分之一。前任。您应该使用 URL、会话、浏览器设置中指定的那个吗?如果没有指定这些会发生什么?什么是后备语言环境?有关一些想法,请参阅https://stackoverflow.com/a/49758067/296555 中的getLanguage() 函数。
  • 提取该语言环境的所有翻译并将它们存储在内存中。这是一个基本查询,用于提取给定语言环境的所有翻译。

    <?pseudocode 
    $locale = 'en_CA';    
    
    // Find all translations for a given locale
    $dbQuery = 'SELECT translation_key, translation
    FROM translations
    WHERE locale = :locale';
    ;
    
  • 将您刚刚提取的条目放入记忆中。

    <?pseudocode 
    $translations = array();
    while loop ($row = $dbQuery) {
        $translations[$row['translation_key']] = $row['translation'];
    }
    
  • 在整个应用程序中,您现在可以通过该数组访问翻译。

    echo $translations['hello'];

您需要在您的应用程序中在每个请求都调用的部分中执行此操作。完成此操作后,您将要开始优化。您可以将数据库结果存储到会话中,这样您就不必在每次页面加载时查询数据库或实现更健壮的缓存形式。

老实说,我认为您的想法是正确的,但魔鬼在细节中,或者他们说。阅读我指向的链接。它并不完美,但它应该可以帮助您相对快速地找到可行的解决方案。

【讨论】:

    【解决方案2】:

    我对其他人给出的关于您的表结构的建议第二,但要回答您的问题,您可以使用 extract

    $row = array(
        col_1 => 'a', 
        col_2 => 'b', 
        col_3 => 'c' 
    )
    
    extract($row);
    
    
    // results in:
    
    //   $col_1  assigned value 'a'
    //   $col_2  assigned value 'b'
    //   $col_3  assigned value 'c'
    

    【讨论】:

      猜你喜欢
      • 2016-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-12
      • 2012-04-17
      • 2014-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多