Laravel 10项目如何将quizapi.io内容翻译为西班牙语、乌克兰语?
实现Laravel站点中QuizAPI内容的多语言翻译方案
一、数据库结构设计
为了灵活支持多语言,推荐采用主表+翻译表的关联结构,避免单表冗余:
- 主表
questions:存储QuizAPI返回的原始英文核心数据(如id,question_text,correct_answer,created_at等),保留原始内容用于后续校对或重新翻译。 - 翻译表
question_translations:存储各语言版本的内容,字段包括:idquestion_id(关联主表ID)locale(语言标识,比如es代表西班牙语、uk代表乌克兰语)question_text(翻译后的问题文本)correct_answer(翻译后的正确答案)incorrect_answers(JSON格式存储翻译后的错误选项)explanation(翻译后的解释文本,若API返回)is_manual(布尔值,标记是否为人工校对内容,优先级高于自动翻译)
在Laravel中通过模型关联实现数据访问:
// app/Models/Question.php class Question extends Model { public function translations() { return $this->hasMany(QuestionTranslation::class); } // 封装获取指定语言翻译的方法 public function translate(string $locale = 'en') { // 优先取人工校对的翻译,无则取自动翻译,再无返回原始英文 $translation = $this->translations() ->where('locale', $locale) ->orderBy('is_manual', 'desc') ->first(); return $translation ?? $this; } }
二、翻译流程实现
1. 拉取QuizAPI数据并入库
用Laravel的Http facade拉取英文数据,存入questions主表:
// 示例:拉取并保存QuizAPI数据 $response = Http::withHeaders([ 'X-Api-Key' => env('QUIZAPI_KEY') ])->get('https://quizapi.io/api/v1/questions', [ 'limit' => 10 ]); foreach ($response->json() as $item) { Question::create([ 'question_text' => $item['question'], 'correct_answer' => $item['correct_answer'], 'incorrect_answers' => json_encode($item['incorrect_answers']), // 其他字段根据API返回补充 ]); }
2. 异步翻译处理
用Laravel队列处理翻译任务,避免阻塞主线程:
- 生成翻译任务类:
php artisan make:job TranslateQuestion - 任务类中调用翻译服务完成翻译并入库:
// app/Jobs/TranslateQuestion.php class TranslateQuestion implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; public function __construct(public Question $question, public string $targetLocale) {} public function handle() { // 初始化翻译客户端(以DeepL为例) $translator = new \DeepL\Translator(env('DEEPL_API_KEY')); // 翻译核心字段 $translatedQuestion = $translator->translateText( $this->question->question_text, 'en', $this->targetLocale ); $translatedCorrectAnswer = $translator->translateText( $this->question->correct_answer, 'en', $this->targetLocale ); // 翻译错误选项数组 $translatedIncorrect = []; foreach (json_decode($this->question->incorrect_answers) as $answer) { $translatedIncorrect[] = $translator->translateText($answer, 'en', $this->targetLocale)->text; } // 存入翻译表(存在则更新,不存在则创建) QuestionTranslation::updateOrCreate( ['question_id' => $this->question->id, 'locale' => $this->targetLocale], [ 'question_text' => $translatedQuestion->text, 'correct_answer' => $translatedCorrectAnswer->text, 'incorrect_answers' => json_encode($translatedIncorrect), 'is_manual' => false ] ); } }
- 触发翻译任务:可在拉取数据后批量分发,或后台手动触发:
// 批量翻译所有问题到西班牙语、乌克兰语 Question::chunk(50, function ($questions) { foreach ($questions as $question) { TranslateQuestion::dispatch($question, 'es'); TranslateQuestion::dispatch($question, 'uk'); } });
三、Laravel本地化适配
- 在
config/app.php中添加支持的语言:
'locales' => ['en', 'es', 'uk'], 'fallback_locale' => 'en',
- 切换语言后,在业务代码中直接调用
translate()方法获取对应语言内容:
// 控制器示例:获取当前语言的问题详情 public function show(Question $question) { $translatedQuestion = $question->translate(app()->getLocale()); return view('questions.show', compact('translatedQuestion')); }
四、后续扩展与优化
- 新增语言支持:只需在
config/app.php的locales数组添加对应语言标识,批量触发翻译任务即可。 - 人工校对功能:在后台添加翻译编辑入口,修改后将
is_manual设为true,确保优先使用人工校对内容。 - 缓存优化:将翻译结果缓存到Redis或Laravel缓存中,避免重复调用翻译API,降低成本。
- 错误重试:为队列任务设置重试次数(如
$tries = 3),处理翻译API调用失败的情况。 - 成本控制:优先选择性价比高的翻译服务,或采用自部署开源翻译模型(如LLaMA)降低长期成本。
内容的提问来源于stack exchange,提问作者Petro Gromovo
相关产品推荐
相关产品推荐

