魔扣论坛

魔扣源码论坛业务
查看: 1127|回复: 7

[经验交流] Discuz!伪静态原理分析

[复制链接]
  • TA的每日心情
    擦汗
    2 小时前
  • 签到天数: 2950 天

    [LV.Master]开坛老将

    7万

    主题

    227

    回帖

    27万

    积分

    管理员

    Rank: 30Rank: 30Rank: 30Rank: 30Rank: 30Rank: 30Rank: 30Rank: 30

    魔扣币
    745559
    贡献
    157861
    威望
    32799

    最佳新人活跃会员热心会员推广达人宣传达人突出贡献优秀版主荣誉管理论坛元老

    发表于 2017-6-4 14:07:21 | 显示全部楼层 |阅读模式
    魔扣币兑换比例:【 50以下 : ¥1 = 10 魔扣币 】丨【 50 - 100 :¥1 = 20 魔扣币】丨【 100以上:¥1 = 30 魔扣币 】

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    伪静态在seo火热的时代,是每个站长都比较关注的问题,discuz!论坛如何伪静态,为什么伪静态失效了,为什么列表页无法实现伪静态,为什么有些页面不是伪静态呢?下面dz官方nxy105从两个角度入手为大家分析下discuz! X2是如何实现伪静态功能。

    第一、Discuz!伪静态是如何作用的

    我们都知道,当我们通过地址访问一个页面的时候,访问的是服务器上的一个实体文件。例如,访问
    http://www.xxx.com/index.html
    复制代码
    , 访问的是网站根目录下的index.html文件。然而,对于论坛,如果每一个页面(主题列表,内容页)都是一个静态的实体文件,那文件的数量将何其之 多,并且不能动态的实时的展现论坛的内容。如果仅仅使用动态访问,那么不利于增强搜索引擎的友好面,因此,我们将使用伪静态,展现形式是.html这样的 静态页面,而实际上依然是通过动态脚本来处理的。

    discuz! X2的伪静态处理利用了服务器的rewrite模块,通过rewrite模块的配置的规则,对请求的url进行转换。

    下面我们以Apache的rewrite模块为例,详细说明一下。
    RewriteRule ^(.*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3&%1
    复制代码
    这是一条Apache的伪静态规则

    rewrite规则匹配的是/forum-XX-XX.html的url请求,经过规则转换后,实际请求的链接是 /forum.php?mod=forumdisplay&fid=XX&page=XX,是不是很熟悉,这就是请求论坛主题列表的动态 链接啦。

    所以问题来了,如果伪静态请求失效/forum-XX-XX.html,提示页面无法显示,有几种错误的可能性呢?

    1、伪静态规则生效了有没有?

    如果服务器不支持rewrite,如果忘了重启服务,如果.htaccess文件放置的位置不对,等等,都可能导致rewrite功能没有运行,这样肯定是不行的哦。所以,先检查下rewrite功能是否正常吧,如果使用空间的话,可以咨询下空间商的说。

    2.规则错误了有没有?

    如果规则是这样的
    RewriteRule ^(.*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdisplay
    复制代码
    少了东西是不是,所以/forum-XX-XX.html只会访问/forum.php?mod=forumdisplay,这样列表页肯定不显示了

    如果规则更夸张一些
    RewriteRule ^(.*)/forum-(\w+)-([0-9]+)\.html$ $1/forumdisplay.php&fid=$2&page=$3&%1
    复制代码
    forumdisplay.php这个文件都没有,页面当然无法显示,这也就解释了过去版本(如X1.5和7.0)的有些规则无法在X2中直接使用的原因了。

    所以规则正确才是页面能够正常访问的前提,如果使用新的规则,发现无法访问了,首先检查规则有没有写错了。(其实这些在论坛后台伪静态设置的地方都可以查的到,根本不用各位站长费心的嘛)

    3、网络正常有没有?

    如果拼命在伪静态中找寻原因,没留意站点已经无法正常访问,是不是有种缘木求鱼的感觉,站点无法访问的原因请参看官方论坛相关教程。

    分析到这一步,相信大家对于伪静态如何起作用已经有一定的了解了,那么我们转向下一个问题。

    第二、伪静态是如何在论坛显示出来的?

    为什么我的站伪静态开启了,但在首页还是显示动态链接呀?那么下面讲解下,伪静态是如何显示出来的。

    了解discuz!的同学应该知道,在论坛模板文件中,所以的url链接都是以动态的形式返回输出的。(在模板中看不到静态链接?是的)按照常规,应该都显示动态链接,那么静态链接又是如何实现。

    在模板文件的footer.htm文件中,有这样一行代码。
    <!--{eval output();}-->
    复制代码
    这段代码解析后,直接调用了function_core.php中的output()函数。
    我们来看看output函数执行了哪些操作。
    if($_G['setting']['rewritestatus'] || !empty($havedomain))
    {
                $content = ob_get_contents();
                $content = output_replace($content);
                ob_end_clean();
                $_G['gzipcompress'] ? ob_start('ob_gzhandler') : ob_start();
                echo $content;
    }
    复制代码
    程 序执行到这里的时候,执行了一个 $content = ob_get_contents();的操作, ob_get_contents()获取当前输出缓存中的所有数据,也就是说,模板返回的页面并没有直接显示给用户,而是被$content变量获取到 了。然后进入output_replace函数执行内容替换(各种替换,不仅仅是伪静态链接替换),最后又echo输出。

    于是,替换工作就放在output_replace函数中,
        if(!empty($_G['setting']['output']['str']['search']))
        {
                    if(empty($_G['setting']['domain']['app']['default'])) {
                        $_G['setting']['output']['str']['replace'] = str_replace('{CURHOST}', $_G['siteurl'], $_G['setting']['output']['str']['replace']);
                    }
                    $content = str_replace($_G['setting']['output']['str']['search'], $_G['setting']['output']['str']['replace'], $content);
        }
    复制代码
    这一部分,替换的是当前站点的域名,将写在模板中的'{CURHOST}'占位符替换为$_G['siteurl']的值。
        if(!empty($_G['setting']['output']['preg']['search']))
        {
                    if(empty($_G['setting']['domain']['app']['default'])) {
                            $_G['setting']['output']['preg']['search'] = str_replace('\{CURHOST\}', preg_quote($_G['siteurl']), $_G['setting']['output']['preg']['search']);
                            $_G['setting']['output']['preg']['replace'] = str_replace('{CURHOST}', $_G['siteurl'], $_G['setting']['output']['preg']['replace']);
                    }
                   $content = preg_replace($_G['setting']['output']['preg']['search'], $_G['setting']['output']['preg']['replace'], $content);
        }     
    复制代码
    这一个部分则是替换伪静态链接,具体的实现过程,我简单介绍下,没有兴趣的同学可以跳过。

    $_G['setting']['output']['preg']['search']数组中保存的数据,类似于
    /<a href\="()forum.php\?mod\=forumdisplay&(amp;)?fid\=(\w+)(&page\=(\d+))?"([^\>]*)\>/e
    对应的$_G['setting']['output']['preg']['replace']中的一条数据为
    rewriteoutput('forum_forumdisplay', 0, '\1', '\3', '\5', '\6')
    这里利用了preg_replace函数的一个特性,当匹配模式中带有e修饰符,用eval进行后向引用替换,即替换变量和执行对应函数。也就是 说,preg_replace将匹配到的子串,以参数的形式传入rewriteoutput函数,rewriteoutput函数返回的值作为替换的内 容。(页面上有几个链接,将会执行几次rewriteoutput函数,这就是开启伪静态略微影响性能的原因)

    问题又来了,伪静态不被替换这是为什么呢?

    原因很简单,因为是在页面输出之前才做的替换,所以一切程序上做可能做的手脚都是浮云了。真正起作用的仅仅是输出之前的链接,是不是符合伪静态的替换规则 呢。类似于/forum.php?mod=viewthread&tid=XX#lastpost这样的链接自然是无法被成功替换的咯

    至此,Discuz伪静态是如何替换并显示的机理就算介绍完毕了。

    会员购买:>> 点击购买 << | 魔扣币购买:>> 点击购买 <<
    承接业务:服务器代维丨网站托管丨SEO
    联系客服:微信:morko-net | QQ:1367681973

    该用户从未签到

    3

    主题

    254

    回帖

    511

    积分

    高级魔扣

    Rank: 4

    魔扣币
    254
    贡献
    254
    威望
    0
    发表于 2017-6-4 17:11:38 | 显示全部楼层
    传说中的沙发???哇卡卡

    该用户从未签到

    3

    主题

    272

    回帖

    549

    积分

    高级魔扣

    Rank: 4

    魔扣币
    274
    贡献
    274
    威望
    0
    发表于 2017-9-16 20:01:21 | 显示全部楼层
    用最美好的心情想念你,魔扣源码论坛用最温暖的笑脸惦挂你,用最宽容的心胸热爱你,用最专注的眼神凝望你,用最忠诚的心灵祝福你。

    该用户从未签到

    1

    主题

    240

    回帖

    481

    积分

    中级魔扣

    Rank: 3Rank: 3

    魔扣币
    240
    贡献
    240
    威望
    0
    发表于 2017-11-18 23:52:07 | 显示全部楼层
    淡定,淡定,淡定……看我轻轻的来,悄悄的走,只带走魔扣源码论坛分享的精品源码,不留下我帅气的文字

    该用户从未签到

    2

    主题

    217

    回帖

    436

    积分

    中级魔扣

    Rank: 3Rank: 3

    魔扣币
    217
    贡献
    217
    威望
    0
    发表于 2017-12-10 17:52:51 | 显示全部楼层
    珍爱生命,果断回帖。

    该用户从未签到

    4

    主题

    255

    回帖

    514

    积分

    高级魔扣

    Rank: 4

    魔扣币
    255
    贡献
    255
    威望
    0
    发表于 2018-6-28 17:25:19 来自手机 | 显示全部楼层
    鼎力支持!!

    该用户从未签到

    3

    主题

    256

    回帖

    515

    积分

    高级魔扣

    Rank: 4

    魔扣币
    256
    贡献
    256
    威望
    0
    发表于 2018-7-23 10:54:03 来自手机 | 显示全部楼层
    既然选择离开,就不要说不会忘记;既然你我没有缘分,就不需要誓言,因为誓言再多也没有用。今天的一切,魔扣源码论坛就像水流过一样不留痕迹。明天、以后,等我们再见的时候,就变成了陌生人。

    该用户从未签到

    1

    主题

    241

    回帖

    483

    积分

    中级魔扣

    Rank: 3Rank: 3

    魔扣币
    241
    贡献
    241
    威望
    0
    发表于 2019-1-2 09:17:40 来自手机 | 显示全部楼层
    为了爱,失恋是必要的;为了光明,黑暗是必要的。',
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    • 联系我们
    • 新浪微博 :
    • 在线客服 :魔扣科技 
    • 源码QQ群 :魔扣源码论坛官方总群
    • 联系邮箱 :charlin#morko.net
    • 微信扫一扫
    快速回复 返回顶部 返回列表