数据库
首页 > 数据库> > php – 多语种MySQL内容:如果指定的语言不可用,如何选择给定的语言?

php – 多语种MySQL内容:如果指定的语言不可用,如何选择给定的语言?

作者:互联网

我正在开发一个多语言网站PHP,并希望获得给定语言的内容(如果可用),如果没有,则在另一个语言中.我将尝试在下面解释我的问题.如果不清楚,请告诉我.

我的桌子:

> content:content_id,url,date
> content_l10n:content_id,l10n_id,标题,描述
> l10n:l10n_id,名称,顺序

第一种情况:

>我的访客说法语.
>我想要显示的内容有英语和法语两种版本.
>该网站应显示法语内容.

→通过JOIN轻松实现.

第二种情况:

>我的访客说法语.
>我想要显示的内容仅提供英文版本.
>网站应显示英文内容.

→如何实现?是否可以在一个请求中?

一些说明:

>这必须可以扩展到两种以上的语言.
>解决方案必须适用于任何一种情况,因为在执行请求之前我不知道内容是否以正确的语言提供.
>越快,越好.
>如果需要,可以更改表格.
>我想选择多个内容行(例如,标题列表).
>有时,标题被翻译但描述为NULL.理想情况下,请求将选择给定语言的标题,但会回退到描述的另一种语言.
>设置回退的顺序会很棒(首先:给定语言,然后是:按顺序ASC排序的l10n语言).

非常感谢您的帮助!先感谢您 !

亲切的问候,

奥利维尔

解决方法:

此解决方案适用于多行,但每种语言需要1 LEFT JOIN,JOIns的顺序指定优先级.

SELECT   c.url, c.date, 
         COALESCE( c1.title, c2.title ),
         COALESCE( c1.description, c2.description )
FROM      content c
LEFT JOIN content_l10n c1 ON (c1.content_id = c.content_id AND c1.l10n_id=$1)
LEFT JOIN content_l10n c2 ON (c2.content_id = c.content_id AND c2.l10n_id=$2)

(注意:我想这里$1和$2是用户的前2种首选语言,并且它们被缓存在会话中,因此不需要使用l10n进行额外的JOIN).

使用表结构,这是设置语言顺序的唯一有意义的方法.您需要一个额外的表来指定每个用户的语言首选项,而不是将顺序存储在l10n表中.所以我们假设你有一张桌子

user_l10n( user_id, l10n_id, order )

我们假设表l10n保留其“order”字段,默认情况下.

如果你这样做:

SELECT   ..., COALESCE(ul.order,l.order) AS order
FROM      
          content      c
JOIN      content_l10n cl USING (content_id)
JOIN      l10n         l  USING (l10n_id)                -- get default language order
LEFT JOIN user_l10n    ul ON    (ul.l10n_id=l.l10n_id    -- get user preferences if available
                                 AND ul.user_id=$user_id)
WHERE search condition on content, etc
ORDER BY content_id, COALESCE(ul.order,l.order)

您将获得所有匹配的文档,以及用户指定的(或默认)排序,因此应用程序可以轻松地对其进行排序.

现在的想法是避免从数据库中检索语言中的所有行,这些行被用户喜欢的语言中的现有翻译“遮蔽”.

执行此操作的自然方法是GROUP BY,但MySQL没有可在此处运行的聚合函数…

你可以做一个从属子查询(标题和描述);这样可以抓住一行,但如果想抓住很多行,可能会非常慢.

但你也可以做点别的!这取决于MySQL的非标准GROUP BY子句的一些阴暗行为……

首先,收集要显示的“content_id”列表(分页搜索查询的结果,无论如何).然后你可以做一些像下面的恐怖事情:

SELECT * FROM
(
    SELECT content_id, title FROM 
    (
        SELECT    c.content_id, c.title
        FROM      
                  content      c
        JOIN      content_l10n cl USING (content_id)
        JOIN      l10n         l  USING (l10n_id)
        LEFT JOIN user_l10n    ul ON    (ul.l10n_id=l.l10n_id AND ul.user_id=$user_id)
        WHERE cl.content_id IN ($list) AND c.title IS NOT NULL
        ORDER BY content_id, COALESCE(ul.order,l.order)
    ) d GROUP BY content_id
) t
JOIN
(
    SELECT content_id, description FROM 
    (
        SELECT    c.content_id, c.description
        FROM      
                  content      c
        JOIN      content_l10n cl USING (content_id)
        JOIN      l10n         l  USING (l10n_id)
        LEFT JOIN user_l10n    ul ON    (ul.l10n_id=l.l10n_id AND ul.user_id=$user_id)
        WHERE cl.content_id IN ($list) AND c.description IS NOT NULL
        ORDER BY content_id, COALESCE(ul.order,l.order)
    ) d GROUP BY content_id
)
USING (content_id)

标签:php,sql,mysql,multilingual
来源: https://codeday.me/bug/20190903/1797461.html