【thinkphp技巧栏】多语言切换

一 开启配置

1 开启多语言

配置config/lang.php,这里给中英示例

<?php
// +----------------------------------------------------------------------
// | 多语言设置
// +----------------------------------------------------------------------

return [
    // 默认语言
    'default_lang' => env('DEFAULT_LANG', 'zh-cn'),
    // 允许的语言列表
    'allow_lang_list' => ['zh-cn', 'en-us'],
    // 多语言自动侦测变量名
    'detect_var' => 'lang',
    // 是否使用Cookie记录
    'use_cookie' => true,
    // 多语言cookie变量
    'cookie_var' => 'think_lang',
    // 多语言header变量
    'header_var' => 'think-lang',
    // 扩展语言包
    'extend_list' => [
        'zh-cn' => [
            app()->getBasePath() . 'lang/zh-cn.php',
        ],
        'en-us' => [
            app()->getBasePath() . 'lang/en-us.php',
        ],
    ],
    // Accept-Language转义为对应语言包名称
    'accept_language' => [
        'zh-cn' => 'zh-cn',
        'en-us' => 'en-us'
    ],
    // 是否支持语言分组
    'allow_group' => true,
];

2 新增语言包

新增在上述配置的extend_list中,指向的语言包

  • 根目录下新增lang文件夹
  • 新增zh-cn.php和en-us.php

新增的语言包格式为

<?php

return [
    'api'=>[
        'test'=>[
            'hello'=>'你好'
        ]
    ],
    'admin'=>[

    ],
    'shop'=>[

    ],
    'device'=>[

    ]
];

注意:ThinkPHP 最多可支持多语言分组两层目录,再往下识别不到,需要自定义修改源码

3 支持自动切换

需要在app/middleware.php下开启多语言自动侦测及自动切换

<?php
// 全局中间件定义文件
return [
     // 多语言加载
     \think\middleware\LoadLangPack::class,
];

二 语言分组可三级以上

1 修改Lang源码

在tp8中的路径为vendor/topthink/framework/src/think/Lang.php

/**
     * 判断是否存在语言定义(不区分大小写)
     * @access public
     * @param string  $name  语言变量
     * @param string  $range 语言作用域
     * @return bool
     */
    public function has(string $name, string $range = ''): bool
    {
        $range = $range ?: $this->range;

        if ($this->config['allow_group'] && strpos($name, '.')) {
            $names = explode('.', $name);
            $i = 0;
            $temp = $this->lang[$range];
            foreach ($names as $key) {
                if(!isset($temp[strtolower($key)])) return false;
                $temp = $temp[strtolower($key)];
                $i++;
            }
            return is_string($temp);
        }

        return isset($this->lang[$range][strtolower($name)]);
    }

    /**
     * 获取语言定义(不区分大小写)
     * @access public
     * @param string|null $name  语言变量
     * @param array       $vars  变量替换
     * @param string      $range 语言作用域
     * @return mixed
     */
    public function get(string $name = null, array $vars = [], string $range = '')
    {
        $range = $range ?: $this->range;

        // 空参数返回所有定义
        if (is_null($name)) {
            return $this->lang[$range] ?? [];
        }

        if ($this->config['allow_group'] && strpos($name, '.')) {
            $names = explode('.', $name);
            $i = 0;
            $temp = $this->lang[$range];
            foreach ($names as $key) {
                if(!isset($temp[strtolower($key)])) {
                    $temp = $name;
                    break;
                }
                $temp = $temp[strtolower($key)];
                if($i > sizeof($names)) break;
                $i++;
            }

            $value = is_string($temp) ? $temp : $name;
        } else {
            $value = $this->lang[$range][strtolower($name)] ?? $name;
        }

        // 变量解析
        if (!empty($vars) && is_array($vars)) {
            /**
             * Notes:
             * 为了检测的方便,数字索引的判断仅仅是参数数组的第一个元素的key为数字0
             * 数字索引采用的是系统的 sprintf 函数替换,用法请参考 sprintf 函数
             */
            if (key($vars) === 0) {
                // 数字索引解析
                array_unshift($vars, $value);
                $value = call_user_func_array('sprintf', $vars);
            } else {
                // 关联索引解析
                $replace = array_keys($vars);
                foreach ($replace as &$v) {
                    $v = "{:{$v}}";
                }
                $value = str_replace($replace, $vars, $value);
            }
        }

        return $value;
    }

2 实现

    public function test(){
        return lang('api.test.hello');
    }

输出:你好

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值