symfony 移动端emoji表情过滤

   公司项目是CMS后台管理。上线了产品告知说某某所不能上外网,上网只能用手机,所以网站要适配手机端。。。。后台只能用手机访问,好奇葩啊。所以系统要适配移动端。
还好前端用的bootstrap框架,这样页面至少样式什么的大致上不会有什么问题。就这样,项目上线了。然后用了一周后发现一个问题,手机输入表情的时候到后台,存数据库的时候报错。问题是数据库编码是utf-8,最多三个字节。而emoji表情是四个字节。。。所以报错也是正常的。试着把某个表编码改成 utf8mb4,按道理是可以得,但是复制一个表情进去,apply的时候还是报错了,所以就想着在代码里面把他过滤掉咯。
因为项目是几个人一起做的,所以每个人的编码风格略有不同。但是万变不离其宗嘛。
本着前端的所有校验都是不可信的原则,我们的php后台肯定要做好把关,不能放过任何一个敌人操作数据库。所以第一步是写一个 Listener  监听事件
注册一个services
app.manage_log_listener:
    class: FilterBundle\EventListener\ExpressionFilterListener
    arguments: ['@router']
    tags:
        - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
        - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse}
EventListener
public function onKernelRequest(GetResponseEvent $event)
{
    if($event->isMasterRequest()){
        $request    = $event->getRequest();
        $conetent   = urldecode($request->getContent());


        $str = preg_replace_callback(    //执行一个正则表达式搜索并且使用一个回调进行替换
            '/./u',
            function (array $match) {
                return strlen($match[0]) >= 4 ? '' : $match[0];
            },
            $conetent);
        if($str != $conetent ){
           throw new MessageException("输入的内容不能包含表情呦");
        }

    }

}
到这里,我们的后台就肯定不会让表情进到数据库了,但是人家一输入表情就直接跳错误页面,肯定是不友好的,所以呢,我们应该在前端交互的时候提示到用户。这样就需要我们在表单提交的时候做好验证了。表单验证无非两种方法,一是form表单直接submit。一是ajax提交。由此,我们就需要写两个校验。
form表单提交
jQuery("form").submit(function (e) {
   var formDate =  jQuery("form").serialize() ;

   var urlDate = decodeURIComponent(formDate);
   var urlDateReal = urlDate.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g, "");
   if(urlDateReal != urlDate ){

      alert("表单含有非法字符1");
      e.preventDefault();
   }
})
这样写呢,过滤是做到了,但是由于全局的js有不好的地方就是,当你的表单时在页面加载之后生成的话,这样js没起作用,怎么办呢?这时候就要我们jQuery的delegate 函数了。api上说1.7之后推荐优先使用on()。我没用。。。。
jQuery(".wrapper").delegate("form","submit",function(e) {
    var formDate =  jQuery("form").serialize() ;
    var urlDate = decodeURIComponent(formDate);
    var urlDateReal = urlDate.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g, "");
    if(urlDateReal != urlDate ){
        if(jQuery(window).cetcmask){
            jQuery(window).cetcmask('输入内容不能含有表情等非法文字21');
            setTimeout("jQuery(window).uncetcmask()",1000);
        }else {
            alert('输入内容不能含有表情等非法文字');
        }
        return false;
    }
});
这样表单提交就可以了,剩下就是ajax提交了,ajax提交前beforeSend方法校验
jQuery.ajaxSetup({
    beforeSend:function () {
     var formDate =  jQuery("form").serialize();
     var urlDate = decodeURIComponent(formDate);
     var urlDateReal = urlDate.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g, "");
     if(urlDateReal != urlDate ){
        if(jQuery(window).cetcmask){
            jQuery(window).cetcmask('输入内容不能含有表情等非法文字ajx');
            setTimeout("jQuery(window).uncetcmask()",1000);
        }else {
            alert('输入内容不能含有表情等      非法文字');
        }
         return false;
     }
    }
});
大功告成!之所以js跟php用不一样的正则匹配,不是为了秀正则,而是因为这两个是我百度来的,试了下都能用,,,所以也懒得去管他了,php的是把每个字符分割,匹配到不是三个字节的就直接过滤,js是比对范围。。。。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值