所有文章

调试discuz

现在他们在做一个论坛,因为人手不够,所以最后决定使用discuz来快速搭建一个论坛。我是很反感这种做法的,大公司怎么会用discuz来搭建自己的社区呢?太丢脸了,这不是告诉别人你没有研发能力吗?不过现在我们这边的研发能力确实很弱,公司不是研发型的,太悲哀了。

我以前从没有接触过discuz,第一次碰到感觉压力很大,什么数据字典,缓存结构,插件机制,模板机制我都不懂,最初他们只叫我做了一点简单的部署问题,比如改个nginx的rewrite规则,改个简单的模板样式,不过渐渐的麻烦的任务也来了。

首先是说他们买了一个模板(真够丢人的),但是这个模板是被加密了的,现在要稍微二次开发一下,比如说改一些url的规则,使得url更加seo友好。其实模板上的url还是很好改的,模板改了之后再加点rewrite到nginx就好了。但是在分页上的url就不好改了,需要去看插件是如何获得数据,输出数据的,结果可恨的是这个插件的开发者把取数据,传数据的过程都给加密了,让人非常郁闷。到最后甚至一度想要把这些加密的方法破解了,不过到底不可能花太多时间去破解,干活才是最重要的。

调了一晚上,终于发现了插件在实现分页的时候调用到了一个discuz的分页函数,在source/function/里面执行grep 'multi' -R *function_core.php这个文件里找到了multi这个函数,然后发现这个函数调用了helper_page::multi这个函数,继续找这个函数。首先找helper_page这个类,那就去source/class/里面找,grep 'multi' -R *helper/helper_page.php里面找到了multi这个静态方法。接下来就是改造这个方法了。大致看了一下,这个函数接受一个url,一个当前页码,以及一些不太重要的东西作为参数,最后输出一段分页代码。在生成html的时候调用到了一个叫做mpurl的方法,这个函数会决定使用什么形式的分隔符来输出url。到这里形势大概就很明朗了,我不必要去改分页函数的逻辑,我只要改mpurl这个函数就好了,如果是这个插件的url,我就让这个函数特殊照顾一下这个插件。

那么现在问题来了,我是该怎么去改造这个函数呢?在它里面加判断?外面加判断?重写一个自定义的函数?我的想法是加入一个自定义的分页函数,multi在调用mpurl的时候会判断一下是调用它还是调用我写的自定义的函数。我想要通过函数名复制来实现,但是我不知道在php里怎么做,所以我就去stackoverflow上问了一下,有个家伙说可以通过变量来保存函数名,比如说$func = 'add';,那么$func(1,2);就等同于add(1,2);了。这个方法有点函数式编程的意思了,不过还是不够,本质上不属于函数名赋值,而且对于调用类里的方法不起作用,我尝试着$func = 'self::add',然后发现总是会报错。后来采用了另一个家伙的方法,写一个帮助函数,在这个帮助函数里面会判断到底是使用dz原生的mpurl还是使用我的my_mpurl,这个方法挺好,我照着做了,终于把分页搞定了。