好久不见两码中特
AB模板網:專注于dede模板,織夢源碼,織夢模板,網站模板,dedecms模板,網站源碼,dedecms教程以及各類手機網站模板和企業網站模板分享.
用戶名:
密碼:
注冊

織夢模板

網站模板搜索
VIP

Discuz!偽靜態原理分析

www.mpahyf.shop / 2014-12-01
偽靜態在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偽靜態是如何替換并顯示的機理就算介紹完畢了。
本文由AB模板網:織夢模板整理發布,轉載請說明出處:http://www.mpahyf.shop
首頁 免費模板 VIP專區 會員中心
收縮
好久不见两码中特 山东快乐扑克开奖时间 股票推荐每日一股9月6日 澳洲幸运10计划软件手机版 股票融资的方法和步骤 试机号分析 湖北十一选五预测 山西十一选五怎么选才能中 吉林11选5彩票通软件 永利app下载官方网站 极速11选5骗局