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