开发者社区> 问答> 正文

继:我朝特有需求之--英文字符占 0.5 个,中文字符占 1 个

继:我朝特有需求之--英文字符占 0.5 个,中文字符占 1 个

展开
收起
社区秘书 2019-12-16 13:42:23 803 0
1 条回答
写回答
取消 提交回答
  • 
    ThinkSNS(简称TS)始于2008年,一款全平台综合性社交系统,为国内外大中小企业和创业者提供社会化软件研发及技术解决方案,目前最新版本为ThinkSNS+。
    
    后端框架使用laravel,每周和 laravel master 保持同步,而后台和 html 5 则采用 vue 开发。语言特性方面,采用 php 7 的严格模式。
    
    言归正传,之所以写继篇,其实是来检讨的,上一次发表了《ThinkSNS+ 如何计算字符显示长度》后,有网友几经测试后告知str_word_count 有问题。
    
    根据ThinkSNS+ 的进度安排,最近在研发支付功能,所以只能使用周末的时间做了一个兼容性更好的计算方法。
    
    需求
    
    重新说下需求:在我天朝 PM 经常会提一种要求,就是例如一个用户名最多输入12个汉字,但是英文可以输入24个,混排也要满足这个规则。
    
    简言之:单字节字符占0.5,多字节字符占1字节。
    
    解决
    
    闲下来的时候看了上篇文章中的算法,其实是没什么问题的,只是兼容性不够好,而且写那个方法时想得过于复杂
    
    也不知道当时脑袋里面都想啥了
    
    我们看上一篇中计算多字节的方法:
    
    $double = str_word_count(preg_replace('([a-zA-Z0-9_])', '', $value)); 计算方法是剔除我们需求中允许的单字节,然后通过 str word count 来获取多字节的个数,其实这个函数是可以获取到的,但是部分系统下是不会成功的。还有一个函数就可以直接获取多字节的个数 mb strlen 修改后如下:
    
    $double = mb_strlen(preg_replace('([a-zA-Z0-9_])', '', $str));
     然后我们就可以正确完成这个需求了,最终实现的 Laravel 验证规则如下:
    
    / 添加长度规则Validator::extend('display_length', function ($attribute, $value, array $parameters) {
        if (empty($parameters)) {
            throw new \InvalidArgumentException('Parameters must be passed');
        }
    
        $min = 0;
        if (count($parameters) === 1) {
            list($max) = $parameters;
        } elseif (count($parameters) >= 2) {
            list($min, $max) = $parameters;
        }
    
        if (! isset($max) || $max < $min) {
            throw new \InvalidArgumentException('The parameters passed are incorrect');
        }
    
        // 计算单字节.
        preg_match_all('/[a-zA-Z0-9_]/', $value, $single);
        $single = count($single[0]) / 2;
    
        // 多子节长度.
        $double = mb_strlen(preg_replace('([a-zA-Z0-9_])', '', $value));
    
        $length = $single + $double;
    
        return $length >= $min && $length <= $max;
    });
    Laravel 通过上面的规则,可以在表单验证规则中直接验证,还支持传入最小值和最大值。
    
    上面的代码都是来自于基于 Laravel 开发的开源程序 ThinkSNS+ 中,ThinkSNS+ 采用 apache-2.0 协议开源,我相信可以作为很多 Laravel 学习者的学习程序之一。
    
    项目地址:GitHub: https://github.com/zhiyicx/thinksns-plus(点击star关注研发动态,感谢大家的支持)
    
    往期研发日记传送门:
    
    《ThinkSNS+基于 Laravel master 分支【研发日记一】》
    
    《ThinkSNS+研发中前端的抉择(webpack/Vue)踩坑日记【研发日记二】》
    
    《基于 Laravel Route 的 ThinkSNS+ Component【研发日记三】》
    
    《如何做到 Laravel 配置可以网站后台配置【研发日记四】》
    
    《ThinkSNS+ 如何计算字符显示长度【研发日记五】》
    
    《基于 Laravel 的 ThinkSNS+ alpha.2 版本发布【研发日记六】》
    
    《聊聊 Laravel 5.5 的 「自动发现」和此刻心情【研发日记七】》
    
    2019-12-17 09:31:21
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载