在网站开发过程中,有的需求可能是要求多语言开发,涉及多个国家的语言,那么怎么实现功能和需求呢?首先我们将网站内容拆分为两类,动态数据和静态描述,什么是动态数据呢?什么是静态描述呢?接下来我说下个人的见解。
一、动态数据
动态数据顾名思义就是依据用户或后台管理人员进行发布、修改、操作的,比如网站的名称、版权、菜单(栏目)及个人的资料等等。这些数据需要由后端进行查询处理,返回或传递给前端,由前端渲染页面或绑定数据。
二、静态描述
静态描述意为程序员在页面代码(模板)中写入的内容,比如个人中心栏目比较常见的修改资料功能,假设个人信息包含以下字段:姓名、年龄、电话、邮箱、住址等等,那么在修改内容的form表单中,我们会将上述几项全部写在页面代码中,而用户的信息将由后端返回。
三、开发模式
我们以thinkphp框架为例,此方式不关乎thinkphp版本,在3.2-5.1版本中均使用,我们将静态描述使用thinkphp内置的语言类“Lang”,关于此类的描述及基本使用不说了,直接看官方手册即可。动态数据由后端进行处理后返回至前端。后端对数据可使用缓存或使用分表模式,均为缓存 翻译 数据模式进行开发。缓存可使用redis;翻译使用百度翻译接口;数据库依据项目需求设定即可。
四、百度翻译接口
百度翻译接口申请、认证、创建项目均不讲述,直接奉上代码;
1、控制器代码
代码语言:javascript复制/**
* 百度翻译数据处理
* @return thinkresponseJson
* @author 申霖
* @time 2019/7/24 0024 下午 8:57
*/
public function baiDuTranslate()
{
$from = input('post.from');
$to = input('post.to');
$query = input('post.content');
if (!$query) {
return json(['code' => 100, 'message' => '缺失必要条件', 'data' => '']);
}
define("CURL_TIMEOUT", 10);
define("URL", "http://api.fanyi.baidu.com/api/trans/vip/translate");
define("APP_ID", "2018022700012****"); //替换为您的APPID
define("SEC_KEY", "raKiRGJBHSx6rWG****");//替换为您的密钥
$args = [
'q' => $query,
'appid' => APP_ID,
'salt' => rand(10000, 99999),
'from' => $from,
'to' => $to,
];
$args['sign'] = buildSign($query, APP_ID, $args['salt'], SEC_KEY);
$ret = callWebServer(URL, $args);
$ret = json_decode($ret, true);
if (isset($ret['error_code'])) {
$errorInfo = error($ret['error_code']);
return json(['code' => $ret['error_code'], 'message' => $errorInfo, 'data' => '']);
} else {
return json(['code' => 200, 'message' => 'success', 'data' => $ret['trans_result'][0]['dst']]);
}
}
2、公共函数代码
代码语言:javascript复制<?php
/**
* Created by PhpStorm.
* User: 申霖
* Date: 2019/7/24 0024
* Time: 下午 8:39
*/
//加密
function buildSign($query, $appID, $salt, $secKey)
{/*{{{*/
$str = $appID . $query . $salt . $secKey;
$ret = md5($str);
return $ret;
}/*}}}*/
//发起网络请求
function callWebServer($url, $args = null, $method = "post",
$testflag = 0, $timeout = CURL_TIMEOUT, $headers = array())
{/*{{{*/
$ret = false;
$i = 0;
while ($ret === false) {
if ($i > 1)
break;
if ($i > 0) {
sleep(1);
}
$ret = callOnce($url, $args, $method, false, $timeout, $headers);
$i ;
}
return $ret;
}/*}}}*/
function callOnce($url, $args = null, $method = "post",
$withCookie = false, $timeout = CURL_TIMEOUT, $headers = array())
{/*{{{*/
$ch = curl_init();
if ($method == "post") {
$data = convert($args);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_POST, 1);
} else {
$data = convert($args);
if ($data) {
if (stripos($url, "?") > 0) {
$url .= "&$data";
} else {
$url .= "?$data";
}
}
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if (!empty($headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
if ($withCookie) {
curl_setopt($ch, CURLOPT_COOKIEJAR, $_COOKIE);
}
$r = curl_exec($ch);
curl_close($ch);
return $r;
}/*}}}*/
function convert(&$args)
{/*{{{*/
$data = '';
if (is_array($args)) {
foreach ($args as $key => $val) {
if (is_array($val)) {
foreach ($val as $k => $v) {
$data .= $key . '[' . $k . ']=' . rawurlencode($v) . '&';
}
} else {
$data .= "$key=" . rawurlencode($val) . "&";
}
}
return trim($data, "&");
}
return $args;
}/*}}}*/
/**
* 接口错误反馈啊
* @param mixed|string $code
* @return mixed|void
*/
function error($code)
{
$data = [
'52000' => ['meaning' => '成功', 'solve' => ''],
'52001' => ['meaning' => '请求超时', 'solve' => '重试'],
'52002' => ['meaning' => '系统错误', 'solve' => '重试'],
'52003' => ['meaning' => '未授权用户', 'solve' => '检查您的
appid 是否正确,或者服务是否开通'],
'54000' => ['meaning' => '必填参数为空', 'solve' => '检查是否少
传参数'],
'54001' => ['meaning' => '签名错误', 'solve' => '请检查您的签名
生成方法'],
'54003' => ['meaning' => '访问频率受限', 'solve' => '请降低您的
调用频率'],
'54004' => ['meaning' => '账户余额不足', 'solve' => '请前往管理
控制台为账户充值'],
'54005' => ['meaning' => '长query请求频繁', 'solve' => '请降低长
query的发送频率,3s后再试'],
'58000' => ['meaning' => '客户端IP非法', 'solve' => '检查个人资料
里填写的 IP地址 是否正确可前往管理控制平台修改IP限制,IP可留空'],
'58001' => ['meaning' => '译文语言方向不支持', 'solve' => '检查译
文语言是否在语言列表里'],
'58002' => ['meaning' => '服务当前已关闭', 'solve' => '请前往管理
控制台开启服务'],
'90107' => ['meaning' => '认证未通过或未生效', 'solve' => '请前往
我的认证查看认证进度'],
];
return $data[$code];
}
3、视图代码
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>百度翻译接口</title>
<meta name="keywords" content="百度,翻译,接口">
<meta name="description"
content="在网站开发过程中,有的需求可能是要求多语言开发,涉及多个国家的语言,那么怎么实现功能和需求呢?首先我们将网站内容拆分为两类,动态数据和静态描述,什么是动态数据呢 ">
<link rel="icon" href="https://www.shenlin.ink/favicon.ico" type="image/x-icon"/>
<link rel="stylesheet" href="/blog/css/layui.css">
<style>
.layui-form {
padding-top: 30px;
}
.layui-input-block {
margin-left: 0;
}
.layui-form-item .layui-input-inline {
float: right;
}
.layui-textarea {
height: 300px;
}
</style>
</head>
<body>
<div class="layui-container">
<form class="layui-form">
<div class="layui-form-item layui-form-text">
<div class="layui-input-block">
<textarea placeholder="请输入内容" name="content" required lay-verify="required"
class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-form-item">
<div class="layui-form-item">
<div class="layui-input-block">
<select name="from" required lay-verify="required">
<option value="auto">请选择语言,默认为自动识别</option>
<option value="zh">中文</option>
<option value="en">英语</option>
<option value="yue">粤语</option>
<option value="wyw">文言文</option>
<option value="jp">日语</option>
<option value="kor">韩语</option>
<option value="fra">法语</option>
<option value="spa">西班牙语</option>
<option value="th">泰语</option>
<option value="ara">阿拉伯语</option>
<option value="ru">俄语</option>
<option value="pt">葡萄牙语</option>
<option value="de">德语</option>
<option value="it">意大利语</option>
<option value="el">希腊语</option>
<option value="nl">荷兰语</option>
<option value="pl">波兰语</option>
<option value="bul">保加利亚语</option>
<option value="est">爱沙尼亚语</option>
<option value="dan">丹麦语</option>
<option value="fin">芬兰语</option>
<option value="cs">捷克语</option>
<option value="rom">罗马尼亚语</option>
<option value="slo">斯洛文尼亚语</option>
<option value="swe">瑞典语</option>
<option value="hu">匈牙利语</option>
<option value="cht">繁体中文</option>
<option value="vie">越南语</option>
</select>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<select name="to" required lay-verify="required">
<option value="en">请选择语言,默认为英语</option>
<option value="zh">中文</option>
<option value="en">英语</option>
<option value="yue">粤语</option>
<option value="wyw">文言文</option>
<option value="jp">日语</option>
<option value="kor">韩语</option>
<option value="fra">法语</option>
<option value="spa">西班牙语</option>
<option value="th">泰语</option>
<option value="ara">阿拉伯语</option>
<option value="ru">俄语</option>
<option value="pt">葡萄牙语</option>
<option value="de">德语</option>
<option value="it">意大利语</option>
<option value="el">希腊语</option>
<option value="nl">荷兰语</option>
<option value="pl">波兰语</option>
<option value="bul">保加利亚语</option>
<option value="est">爱沙尼亚语</option>
<option value="dan">丹麦语</option>
<option value="fin">芬兰语</option>
<option value="cs">捷克语</option>
<option value="rom">罗马尼亚语</option>
<option value="slo">斯洛文尼亚语</option>
<option value="swe">瑞典语</option>
<option value="hu">匈牙利语</option>
<option value="cht">繁体中文</option>
<option value="vie">越南语</option>
</select>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="*">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<script src="/blog/jquery-2.1.4.min.js"></script>
<script src="/blog/layui.js"></script>
<script>
layui.use(['layer', 'form'], function () {
var form = layui.form, layer = layui.layer;
form.on('submit(*)', function (data) {
$.ajax({
type: 'post',
url: '/open/ai/baiDuTranslate.html',
data: data.field,
async: false,
dataType: "json",
success: function (res) {
if (res.code === 200) {
layer.msg(res.message, {icon: 1, time: 1000}, function () {
layer.open({
'title': '翻译结果',
'content': "<textarea class='layui-textarea res-area'>" res.data "</textarea>"
})
});
} else {
layer.msg(res.data);
}
},
error: function () {
layer.msg("接口错误");
}
});
return false;
});
});
</script>
</body>
</html>