微构网络

长沙论坛开发:Discuz发布特殊字符帖子内容为空的临时解决方案

2016-05-06 20:55 栏目:技术教程 查看(2,921)

最近发现了一个非常有意思的问题,那就是我们可以在几乎所有的基于Discuz的论坛中发布标题和帖子都为空的内容,这种情况在正常的运营过程中是不可能出现的,而且出现之后肯定是非常影响用户体验的。比如一整版都被刷成了空白,想想都要气炸了。说到这个问题,我们先来看一张图:

3r3w

这张图很多人应该都看到过,没错,这就是从我的手机上截图下来的,在我印象中好像ios自带输入法都会有这种称之为emoji的表情,而且现在非常流行。这种表情其实也算是一种特殊符号,大家可以在基于Discuz的论坛中发布这样的内容,我们会发现内容是空白的(discuz默认是不允许发布空的内容的);通过我们的测试很多开源的程序发布诸如这类特殊符号的时候,最终显示出来的是空白;再比如输入“€”符号(欧元符号)也会是这样。

大家都知道在discuz发布帖子的时候对应执行的脚本在source/module/forum/forum_post.php中,通过分析,我们可以追踪到我们输入的特殊字符在执行insert语句的时候依然不是空的,而插入到数据库中后就是空的了,当然显示出来也是空的了。

实际上就是因为这些特殊字符的某些原因,造成这种字符的存储问题。实际上我们也会看到很多知名站点是支持emoji的,当然他们是做了处理的,实际上针对这点,在github上有很多开源的项目,如果愿意折腾可以让我们的项目也支持。当然除了emoji外,其实还有其他的一些特殊字符要处理。

于是有些人就会说,这么麻烦,还是不需要支持吧,我直接把这样的帖子给删除了。但手动删除显然不太好了,于是就有了这个临时的解决方案,其实对于我来说并不算解决方案,因为这并没有从根本上解决问题。它唯一做的事情就是自动删帖,但有人提出这样的需求还是照干吧。

上面我已经说了,在执行insert的时候所对应的参数值还是不为空的,那么就是在存入数据库的时候变成了空的。于是就可以这样子,在执行内容insert脚本后面紧跟着做一个判断,再次查询刚刚插入的数据,然后判断对应的内容是否为空,如果为空执行删除这条记录的语句,然后反馈提示给用户说不能发布这样的内容。

通过查看discuz的源代码,我们可以在source/include/post/post_newreply.php中找到回帖开始执行insert的代码,就是在其中的newreply()方法,而相应的发布帖子对应的就是同目录下的post_newthread.php。以回帖为例,我们可以在newreply()执行的后面,也就是找到如下代码:

$modpost->attach_before_methods('newreply', $bfmethods);
$modpost->attach_after_methods('newreply', $afmethods);
$return = $modpost->newreply($params);
$pid = $modpost->pid;

在这段代码后面加入以下代码

//通过返回的pid获取插入的信息
$databypid=C::t('forum_post')->fetch_by_pid_condition($tableid, $pid,'','message');
//判断message是否为''
if(empty($databypid['message'])){
    DB::delete('forum_post', array('pid' => $pid));//删除message为''时的整个记录
    showmessage('不能输入特殊字符或表情!');//给用户提示
}

流程就是跟上面提到的一样,当然在发帖的中间,我们应该在判断中加入对标题的判断,也就是除了message这个字段外,还应该加入subject字段加进来一起做判断。这种其实是退一步的方式,因为至少付出了多余的两条sql操作,实际上如果我们确定了这些字符对应的范围,然后使用正则在执行insert前就可以过滤掉。

转载请注明出处:长沙论坛开发:Discuz发布特殊字符帖子内容为空的临时解决方案 - 微构网络
分享:

您可能遇到的问题?

搜索微构网络的干货:

值班:15574303608 业务:在线咨询 技术:在线咨询

电话:0731-83862683 售后:在线咨询 邮箱:server@csweigou.com

地址:长沙市五一西路锦绣中环1116(五一广场平和堂对面)