Discuz!官方免费开源建站系统

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

[已解决] 标题字数限制已经完美修改『这属于代码BUG,请官方注意』

[复制链接]
shenzhenfutian 发表于 2014-10-25 23:48:37 | 显示全部楼层 |阅读模式
本帖最后由 shenzhenfutian 于 2014-10-26 04:08 编辑

好久没弄Discuz了,一个朋友让我解决下说发帖标题字数限制的问题,看了下代码,这纯粹属于代码上的Bug,这个敲代码的能不能稍微细心点。
现在的网友大部分是按照 https://discuz.dismall.com/thread-2388129-1-1.html 这个链接修改的,这里面也犯了好多错误,等下一一表明。
先说明下问题所在,朋友的论坛是UTF8版本,以下不注明一律是UTF8版本,GBK版本按照我下面的修改修改就行了,很简单的,GBK是定长的,比UTF8非定长的好修改很多。
首先是发帖的时候 还可输入 35 个字符,大家看明白,这是字符,不是字数。简单说明下,一个UTF8中文占用2-4个字节,是非定长的,这就是产生问题的关键所在。如果不是程序猿,你就这么理解,一个中文字,有可能是2个字节,也有可能是4个,所以导致了Discuz在判断的时候如果按80算,那么永远也不可能达到80个明面上的字数。而这个问题Discuz其实代码里已经解决了,只是写代码的人太不细心了,直接导致了问题所在。而这也是上面发的链接的修改不彻底的问题所在,上面的修改把数字从80改成了120,这绝对是错误的,看了下仁兄还是team的,表示汗。数据库里面表字段的是char(80),如果按照英文字母来发帖,保证你悲剧,虽然你修改了JS,但是PHP里面还有代码Bug呢,尴尬。那我就来帮你改成显示多少字数吧。
以下是核心教程:
找到并打开/source/function/function_core.php,寻找到827行:
function dstrlen($str) {
        if(strtolower(CHARSET) != 'utf-8') {
                return strlen($str);
        }
        $count = 0;
        for($i = 0; $i < strlen($str); $i++){
                $value = ord($str[$i]);
                if($value > 127) {
                        $count++;
                        if($value >= 192 && $value <= 223) $i++;
                        elseif($value >= 224 && $value <= 239) $i = $i + 2;
                        elseif($value >= 240 && $value <= 247) $i = $i + 3;
                }
                $count++;
        }
        return $count;
}
写这个函数的,你在我注明红色的地方加了$count++;是几个意思啊,表示非常汗,其实这个函数写的很好了,都已经解决问题了,就因为你老人家加了这个,全部功能失效。大家把这个去掉,就修改好了PHP部分了。
修改成以下:
function dstrlen($str) {
        if(strtolower(CHARSET) != 'utf-8') {
                return strlen($str);
        }
        $count = 0;
        for($i = 0; $i < strlen($str); $i++){
                $value = ord($str[$i]);
                if($value > 127) {
                        if($value >= 192 && $value <= 223) $i++;
                        elseif($value >= 224 && $value <= 239) $i = $i + 2;
                        elseif($value >= 240 && $value <= 247) $i = $i + 3;
                }
                $count++;
        }
        return $count;
}



接下来是Javascript部分修改,让浏览器判断正确的标题字数。
找到并打开/static/js/common.js,找到112行:
function mb_strlen(str) {
        var len = 0;
        for(var i = 0; i < str.length; i++) {
                len += str.charCodeAt(i) < 0 || str.charCodeAt(i) > 255 ? (charset == 'utf-8' ? 3 : 2) : 1;
        }
        return len;
}
修改成:
function mb_strlen(str) {
        var len = 0;
        var strValue = '';
        for(var i = 0; i < str.length; i++) {
                strValue = str.charCodeAt(i);
                if(strValue > 127) {
                        if(strValue >= 192 && strValue <= 223) i++;
                        else if(strValue >= 224 && strValue <= 239) i = i + 2;
                        else if(strValue >= 240 && strValue <= 247) i = i + 3;
                }
                len++;
        }
        return len;
}



继续找到127行:
function mb_cutstr(str, maxlen, dot) {
        var len = 0;
        var ret = '';
        var dot = !dot ? '...' : dot;
        maxlen = maxlen - dot.length;
        for(var i = 0; i < str.length; i++) {
                len += str.charCodeAt(i) < 0 || str.charCodeAt(i) > 255 ? (charset == 'utf-8' ? 3 : 2) : 1;
                if(len > maxlen) {
                        ret += dot;
                        break;
                }
                ret += str.substr(i, 1);
        }
        return ret;
}
修改成:
function mb_cutstr(str, maxlen, dot) {
        var len = 0;
        var ret = '';
        var dot = !dot ? '...' : dot;
        var strValue = '';
        maxlen = maxlen - dot.length;
        for(var i = 0; i < str.length; i++) {
                strValue = str.charCodeAt(i);
                if(strValue > 127) {
                        if(strValue >= 192 && strValue <= 223) i++;
                        else if(strValue >= 224 && strValue <= 239) i = i + 2;
                        else if(strValue >= 240 && strValue <= 247) i = i + 3;
            }
            len++;
                if(len > maxlen) {
                        ret += dot;
                        break;
                }
                ret += str.substr(i, 1);
        }
        return ret;
}



继续找到1756行:
function strLenCalc(obj, checklen, maxlen) {
        var v = obj.value, charlen = 0, maxlen = !maxlen ? 200 : maxlen, curlen = maxlen, len = strlen(v);
        for(var i = 0; i < v.length; i++) {
                if(v.charCodeAt(i) < 0 || v.charCodeAt(i) > 255) {
                        curlen -= charset == 'utf-8' ? 2 : 1;
                }
        }
        if(curlen >= len) {
                $(checklen).innerHTML = curlen - len;
        } else {
                obj.value = mb_cutstr(v, maxlen, 0);
        }
}
修改成:
function strLenCalc(obj, checklen, maxlen) {
        var v = obj.value, charlen = 0, maxlen = !maxlen ? 200 : maxlen, curlen = 0, strValue = '';
        for(var i = 0; i < v.length; i++) {
                strValue = v.charCodeAt(i);
                if(strValue > 127) {
                        if(strValue >= 192 && strValue <= 223) i++;
                        else if(strValue >= 224 && strValue <= 239) i = i + 2;
                        else if(strValue >= 240 && strValue <= 247) i = i + 3;
                }
                curlen++;
        }
        if(maxlen >= curlen) {
                $(checklen).innerHTML = maxlen - curlen;
        } else {
                obj.value = mb_cutstr(v, maxlen, 0);
        }
}



如果开启了门户的话,找到并打开/static/js/portal.js,找到329行按照上面修改最后一部分的function strLenCalc修改就好了。

自此全部修改完成,现在可以你在标题输入多少字就是按字数来判断了,完美显示字数,你完全可以发足80个字数的标题,谁闲的蛋疼标题都80个字啊。
如果完美主义者,把还可输入 35 个字符字符这两个字改成字数就好了(还可输入 35 个字数),就不会给用户造成困扰了。
到现在为止,输入多少字就按人类正常思维算多少字数,而不是算字符数。
注:以上修改针对UTF8版本GBK版本请自行修改函数里面的判断条件,GBK是定长的,中文两个字节,更简单了,大家自行按照以上文件修改就OK。
还有就是刚注册的账号,好久没碰过Discuz,大家见谅。目测了下好多个版本都存在这个问题,这个DZ team的人难道就一直没发现问题所在吗,尴尬。

-----------------------------------------------------------------------------------------------------------------
别发私信了,有问题加扣扣:1463899980。不保证在线,要是有空见到了帮你们处理下没问题。








 楼主| shenzhenfutian 发表于 2014-10-25 23:52:49 | 显示全部楼层
乱码了 悲剧
回复

使用道具 举报

crx349 发表于 2014-10-26 00:28:34 | 显示全部楼层
感谢分享了~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|Discuz! 官方站 ( 皖ICP备16010102号 )star

GMT+8, 2024-11-16 11:08 , Processed in 0.027474 second(s), 7 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表