[小技巧]百度翻译api处理I18N未命中的情况 [ 2.0 版本 ]
原文链接:http://www.51siyuan.cn/94.html
参考源码:http://www.51siyuan.cn/code.html
如果翻译的消息在消息源文件里找不到,Yii 将直接显示该消息内容。这样一来当你的原始消息是一个有效的冗长的文字时会很方便。 然而,有时它是不能实现我们的需求。你可能需要执行一些自定义处理的情况, 这时请求的翻译可能在消息翻译源文件找不到。 这可通过使用
yii\i18n\MessageSource::EVENT_MISSING_TRANSLATION - yii\i18n\MessageSource
的事件来完成。
例如,你可能想要将所有缺失的翻译做一个明显的标记,这样它们就可以很容易地在页面中找到。 为此,你需要先设置一个事件处理程序。这可以在应用程序配置中进行:
'components' => [
// ...
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\PhpMessageSource',
'fileMap' => [
'app' => 'app.php',
'app/error' => 'error.php',
],
'on missingTranslation' => ['app\components\TranslationEventHandler', 'handleMissingTranslation']
],
],
],
],
现在,你需要实现自己的事件处理程序,以下代码通过调用百度翻译api实现没命中的情况下先翻译并保存数据库再返回翻译结果:
<?php
namespace app\components;
use app\models\I18nMessage;
use app\models\I18nSourceMessage;
class TranslationEventHandler
{
/**
* @param \yii\i18n\MissingTranslationEvent $event
*/
public static function missingTranslation($event)
{
//http://fanyi.baidu.com/v2transapi?from=zh&query=世界&to=en
// 当语言没命中的时候用百度翻译并保存到数据库
$model = I18nSourceMessage::find()->where(['category' => $event->category, 'message' => $event->message])->one();
if ($model == null) {
$model = new I18nSourceMessage();
$model->category = $event->category;
$model->message = $event->message;
$model->save();
}
$messageModel = I18nMessage::find()->where(['id' => $model->id, 'language' => $event->language])->one();
if ($messageModel == null) {
$messageModel = new I18nMessage();
$messageModel->language = $event->language;
$messageModel->id = $model->id;
$messageModel->translation = self::translate($event->message, 'en', self::parseLanguage($event->language));
$messageModel->save();
}
$event->translatedMessage = $messageModel->translation;
}
public static function parseLanguage($language)
{
// 参考百度翻译api自己添加其他语言的map(yii - baidu)
$languageMap = [
'zh-CN' => 'zh'
];
return $languageMap[$language];
}
//百度翻译
public static function translate($text, $from , $to)
{
$url = "http://fanyi.baidu.com/v2transapi";
$data = array (
'from' => $from,
'to' => $to,
'query' => $text
);
$data = http_build_query($data);
$ch = curl_init ();
curl_setopt ($ch, CURLOPT_URL, $url );
curl_setopt ($ch, CURLOPT_REFERER, "http://fanyi.baidu.com" );
curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; rv:37.0) Gecko/20100101 Firefox/37.0' );
curl_setopt ($ch, CURLOPT_HEADER, 0 );
curl_setopt ($ch, CURLOPT_POST, 1 );
curl_setopt ($ch, CURLOPT_POSTFIELDS, $data );
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ($ch, CURLOPT_TIMEOUT, 10 );
$result = curl_exec($ch);
curl_close($ch);
$result = json_decode($result, true);
if (!isset($result['trans_result']['data']['0']['dst'])){
return false;
}
return $result['trans_result']['data']['0']['dst'];
}
}
yii\i18n\MissingTranslationEvent::translatedMessage
是由事件处理程序设置,它将显示翻译结果。
当然你可以直接设置所有国际化语言都用 DB 来管理,一开始通过这种方法收集所有消息源,而不用那么麻烦自己去文件里定义。翻译结果不可能完全符合你意,自己做个 crud 界面改翻译结果~
yidashi
注册时间:2015-06-26
最后登录:2018-11-07
在线时长:86小时19分
最后登录:2018-11-07
在线时长:86小时19分
- 粉丝77
- 金钱10060
- 威望240
- 积分13320
共 2 条评论
大师!大师!大师!
师你妹啊。。。
易大师,yidashi,我说这ID怎么这么眼熟,原来我的贱就是你的贱