语言包解决方案

前言

以前使用过ecshop,语言包,需要先去定义映射,然后才能使用,这样开发起来非常繁琐,现在的项目需要用到语言包用到的一个方案,记录一下。

大致思路

1.用中文作为键,翻译的语言包作为值。定义语言包文件

2.写一个递归函数来翻译变量。

3.php 中在向前端分配变量的时候,统一调用这个函数,这样保证php所有渲染过的数据,都是被翻译过的。

4.html中同样用这个递归函数去翻译中文

注意的地方。

在我们开发项目的时候,中文全部使用单引号,包括js,php。 这样,我们可以用扫描脚本的方式,将中文导出,不需要人工去查找。

PHP中,代码如下

initLocal($local);
    }

    /**
     * 直接访问属性
     * @param $name
     * @return mixed
     */
    public function __get($name)
    {
        return $this->$name;
    }

    /**
     * 获取实例
     *
     * @return object
     */
    public static function getInstance()
    {
        if (!self::$instance instanceof self) {
            self::$instance = new self;
        }
        return self::$instance;
    }


    /**
     * 为html页面提供语言支持
     */
    public function langHtml($key, $replace = null)
    {

        $str = val(self::$langData, trim($key), $key);

        //转数组
        $replaceArr=is_array($replace)?$replace:[$replace];

        if(!is_null($replace)){
            foreach($replaceArr as $v){
                $str = preg_replace('/'.self::REPLACE_STRING.'/', $v, $str,1);
            }
        }

        return $str;
    }

    /**
     * 递归处理数组翻译
     * @param $arr
     * @param int $mode 0=翻译key和value,1=翻译value,2=翻译key
     */
    public function langArray($arr,$mode=0)
    {
        if(is_array($arr)){
            foreach ($arr as $k=>$v){
                if($mode==1){
                    //只翻译value
                    $arr[$k]=$this->langArray($v,$mode);
                }else{
                    //翻译key
                    $kLang=langHtml($k);
                    $arr[$kLang]=$this->langArray($v,$mode);
                    if($kLang!=$k) unset($arr[$k]);
                }

            }
        }else{
            if(in_array($mode,[0,1])){
                //需要翻译value
                $arr=$this->langHtml($arr,$mode);
            }
        }

        return $arr;
    }


    /**
     * 将csv文件导成前端语言包文件,生成in-en-html.php
     */
    public function makeLangHtmlFileFromCsv()
    {
        self::$langData=[];

        $arrFile = ['operate_manage.csv', 'app_api.csv','caiwu.csv'];//html csv源文件
        foreach ($arrFile as $v) {
            $file = fopen(dirname(__FILE__) . '/in-en/' . $v, "r");
            while (!feof($file)) {
                $tmp = fgetcsv($file);

                if (empty($tmp[0]) || empty($tmp[1])) continue;

                //文件理没有出现过,且没有被翻译过
                self::$langData[$tmp[0]] = $tmp[1];

            }
            fclose($file);
        }
        $content = 'addCookie(self::LANG_COOKIE_NAME, $lang);
    }

    /**
     * 获取当前的语言环境
     * @return string
     * @throws Exception
     */
    public function getLangFromCookie()
    {
        return GetOB('Util.Cookie')->getCookie(self::LANG_COOKIE_NAME);
    }


    //防止克隆
    private function __clone()
    {
    }


    /**
     * 扫描目录,导出需要翻译的中文
     * @param bool $diff
     *
     */
    public function scanDir($diff = true)
    {
        $projectDir = $this->getProjectRoot();//项目目录
        $scanDir = ['/api/OB', '/account_manage/App','/operate_manage/App'];//需要文件目录'operate_manage/App'


        foreach ($scanDir as $v) {
            $dir = $projectDir . $v;
            $this->scanFile($dir);
        }

        if ($diff) {
            //去掉翻译过的
            $inEnData = include dirname(__FILE__) . '/in-en/in-en-html.php';
            $keyInEnData = array_keys($inEnData);
            foreach ($this->outData as $k => $v) {
                if (in_array($v, $keyInEnData)) {
                    unset($this->outData[$k]);
                }
            }

            foreach ($this->outHtml as $k => $v) {
                if (in_array($v, $keyInEnData)) {
                    unset($this->outHtml[$k]);
                }
            }
        }

        $data=[$this->outData,$this->outHtml];
        foreach ($data as $k=>$v){
            $v= array_unique($v);
            switch ($k){
                case 0: $filename='zh-cn-p.csv';break;
                case 1: $filename='zh-cn-h.csv';break;
            }

            $fileDir=dirname(__FILE__)."/tmp";
            if(!is_dir($fileDir))mkdir($fileDir);

            $zhcnFile = fopen($fileDir. "/$filename", "w");


            //组装导出数据
            foreach ($v as $key => $value) {

                fputcsv($zhcnFile, [$value], ',');
            }
            fclose($zhcnFile);
        }

        die;

    }

    /**
     * 递归扫描文件
     * @param $dir
     * @return bool
     */
    private function scanFile($dir)
    {

        $projectRoot = $this->getProjectRoot();
        $skipDir = [$projectRoot . '/api/OB/Lang'];//跳过的文件目录

        $skipFile = [
            $projectRoot . '/api/OB/Util/MathUtil.class.php',
            $projectRoot . '/api/OB/Util/DateUtil.class.php',
            $projectRoot . '/api/OB/Util/Sms.class.php',
            $projectRoot . '/api/OB/Util/SendMail.class.php',
            $projectRoot . '/api/OB/Api/BluePay.class.php',
            $projectRoot . '/api/OB/Api/Auth.class.php',
            $projectRoot . '/api/OB/Api/ApiAction.class.php',
            $projectRoot . '/operate_manage/App/View/useradmin/show.html',
            $projectRoot . '/operate_manage/App/View/index/modal.html',

        ];//跳过的文件
        if (!is_dir($dir) || in_array($dir, $skipDir)) return false;
        $handle = opendir($dir);
        if ($handle) {
            while (($fl = readdir($handle)) !== false) {
                $temp = $dir . DIRECTORY_SEPARATOR . $fl;
                //如果不加  $fl!='.' && $fl != '..'  则会造成把$dir的父级目录也读取出来
                if (is_dir($temp) && $fl != '.' && $fl != '..') {
                    $this->scanFile($temp);
                } else {
                    if ($fl != '.' && $fl != '..' && !in_array($temp, $skipFile)) {

                        if (strpos($temp, '.php')) {
                            $content = file_get_contents($temp);
                            if (preg_match_all("/['\"]([\x{4e00}-\x{9fa5}!!,,a-zA-Z_]+[\x{4e00}-\x{9fa5}]+[\x{4e00}-\x{9fa5}!!,,a-zA-Z_0-9]*)['\"]/u", $content, $outArr)) {
                                $this->outData = array_merge($this->outData, $outArr[1]);
                            }
                        } elseif (strpos($temp, '.html')) {
                            $content = file_get_contents($temp);
                            if (preg_match_all("/([\x{4e00}-\x{9fa5}!!,,a-zA-Z_\/\/\\%,\[\],\(\)a-zA-Z_0-9\&\;\s:]*)/u", $content, $outArr)) {
                                foreach ($outArr[1] as $k => $v) {
                                    //去掉注释
                                    if (preg_match('/[\/\/\
                    

你可能感兴趣的:(语言包解决方案)