• Discuz!伪静态原理分析


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

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

    我们都知道,当我们通过地址访问一个页面的时候,访问的是服务器上的一个实体文件。例如,访问

    1. http://www.xxx.com/index.html
    复制代码

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

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

    下面我们以Apache的rewrite模块为例,详细说明一下。

    1. 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.规则错误了有没有?

    如果规则是这样的

    1. RewriteRule ^(.*)/forum-(w+)-([0-9]+).html$ $1/forum.php?mod=forumdisplay
    复制代码

    少了东西是不是,所以/forum-XX-XX.html只会访问/forum.php?mod=forumdisplay,这样列表页肯定不显示了

    如果规则更夸张一些

    1. 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文件中,有这样一行代码。

    1. <!--{eval output();}-->
    复制代码

    这段代码解析后,直接调用了function_core.php中的output()函数。
    我们来看看output函数执行了哪些操作。

    1. if($_G['setting']['rewritestatus'] || !empty($havedomain))
    2. {
    3.             $content = ob_get_contents();
    4.             $content = output_replace($content);
    5.             ob_end_clean();
    6.             $_G['gzipcompress'] ? ob_start('ob_gzhandler') : ob_start();
    7.             echo $content;
    8. }
    复制代码

    程序执行到这里的时候,执行了一个 $content = ob_get_contents();的操作, ob_get_contents()获取当前输出缓存中的所有数据,也就是说,模板返回的页面并没有直接显示给用户,而是被$content变量获取到了。然后进入output_replace函数执行内容替换(各种替换,不仅仅是伪静态链接替换),最后又echo输出。

    于是,替换工作就放在output_replace函数中,

    1.     if(!empty($_G['setting']['output']['str']['search']))
    2.     {
    3.                 if(empty($_G['setting']['domain']['app']['default'])) {
    4.                     $_G['setting']['output']['str']['replace'] = str_replace('{CURHOST}', $_G['siteurl'], $_G['setting']['output']['str']['replace']);
    5.                 }
    6.                 $content = str_replace($_G['setting']['output']['str']['search'], $_G['setting']['output']['str']['replace'], $content);
    7.     }
    复制代码

    这一部分,替换的是当前站点的域名,将写在模板中的'{CURHOST}'占位符替换为$_G['siteurl']的值。

    1.     if(!empty($_G['setting']['output']['preg']['search']))
    2.     {
    3.                 if(empty($_G['setting']['domain']['app']['default'])) {
    4.                         $_G['setting']['output']['preg']['search'] = str_replace('{CURHOST}', preg_quote($_G['siteurl']), $_G['setting']['output']['preg']['search']);
    5.                         $_G['setting']['output']['preg']['replace'] = str_replace('{CURHOST}', $_G['siteurl'], $_G['setting']['output']['preg']['replace']);
    6.                 }
    7.                $content = preg_replace($_G['setting']['output']['preg']['search'], $_G['setting']['output']['preg']['replace'], $content);
    8.     }     
    复制代码

    这一个部分则是替换伪静态链接,具体的实现过程,我简单介绍下,没有兴趣的同学可以跳过。

    $_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伪静态是如何替换并显示的机理就算介绍完毕了。

    这几天觉得,discuz伪静态很好研究,又发现自己论坛的导读功能要贴伪静态,如是乎,就出了这个教程贴.....

    /forum.php?mod=guide&view=digest  这样的地址真的不好看,然后discuz至少是x2.5还没有给导读加伪静态规则,x3.0我就不知道了,没仔细去看

    欢迎访问 http://www.sxwlkj.net 上线网络科技提供

    接下来进入正题.....


    1.function_admincp.php  // 添加后台界面出现  1384行

    $data['rulesearch']['forum_guide'] = 'guide-{action}-{page}.html';
    $data['rulereplace']['forum_guide'] = 'portal.php?mod=guide&view={action}&page={page}';
    $data['rulevars']['forum_guide']['{action}'] = '([a-z0-9_-]+)';
    $data['rulevars']['forum_guide']['{page}'] = '([0-9]+)';

    2.function_admincp.php 替换url地址规则 1340行


    if(in_array('forum_guide', $_G['setting']['rewritestatus'])) {
         $data['search']['forum_guide'] = "/".$_G['domain']['pregxprw']['forum']."?mod=guide&(amp;)?view=(w+)(&page=(d+))?"([^>]*)>/e";
         $data['replace']['forum_guide'] = "rewriteoutput('forum_guide', 0, '\1', '\3', '\5', '\6')";
    }//自己添加的导读导航


    3.替换函数加个导读判断 function_core.php

    function rewriteoutput($type, $returntype, $host)

    } elseif($type == 'forum_guide') { // 添加的
                    list(,,, $action, $page, $extra) = func_get_args();
                    $r = array(
                            '{action}' => $action,
                            '{page}' => $page ? $page : 1,
    );//添加的


    4.添加语言  lang_admincp.php  //添加

    最后结果如下面截图  后台


    <ignore_js_op> 

    最后结果如下面截图  前台

    <ignore_js_op> 

    QQ截图20130609171641.jpg (51.15 KB, 下载次数: 5)

     

  • 相关阅读:
    【乱侃】How do they look them ?
    【softeware】Messy code,some bug of Youdao notebook in EN win7
    【随谈】designing the login page of our project
    【web】Ad in security code, making good use of resource
    SQL数据库内存设置篇
    关系数据库的查询优化策略
    利用SQL未公开的存储过程实现分页
    sql语句总结
    sql中使用cmd命令注销登录用户
    SQLServer 分页存储过程
  • 原文地址:https://www.cnblogs.com/lingzhao/p/4439783.html
Copyright © 2020-2023  润新知