帖子查看數及附件下載數延遲更新,可明顯降低訪問量很大的站點的服務器 (主要針對 MySQL
的壓力) 負擔,建議開啓本功能。但對其中的程序流程和功能細節,可能有很多站長不是很清晰,在這裏碼點文字給大家串一串,希望在這個地方以後遇到問題,可
以為大家提供一些思路。

一、如何開啓延遲更新

涉及的文件:source/admincp/admincp_setting.php
搜索關鍵字:delayviewcount

開啓延遲更新在論壇後台的 「全局 » 優化設置 » 服務器優化」 中,按照需要在 「點擊數延遲更新」 下勾選複選框就 OK 了,這個地方很簡單。
在 「點擊數延遲更新」 下有 「主題瀏覽量」 和 「附件下載量」 兩項設置,但他們卻是保存在同一個設置項目 delayviewcount
中的,所以這裏從程序上做了點小處理。提交過來的兩個選項,如果勾選其值即為 1,不勾選其值即為 0,將其拼接成二進制的字符,然後再將其轉換為十進制後存
到數據庫中的。即為:
附件下載量關閉值為 0,主題瀏覽量關閉值為 0,拼接為二進制的數字為 00,轉換為十進制為 0;
附件下載量關閉值為 0,主題瀏覽量開啓值為 1,拼接為二進制的數字為 01,轉換為十進制為 1;
附件下載量開啓值為 1,主題瀏覽量關閉值為 0,拼接為二進制的數字為 10,轉換為十進制為 2;
附件下載量開啓值為 1,主題瀏覽量開啓值為 1,拼接為二進制的數字為 11,轉換為十進制為 3 。

所以在數據表 (pre_common_setting 表) 中存儲的值 (skey = 'delayviewcount' 時,svalue
對應的值) 即為 0 、 1 、 2 、 3 。

二、主題瀏覽量延遲更新的實際使用

涉及的文件:source/module/forum/forum_viewthread.php
搜索關鍵字:function viewthread_updateviews

涉及的文件:source/function/function_misc.php
搜索關鍵字:function updateviews

主題的瀏覽量即為查看數,在瀏覽一個主題時 (訪問 forum_viewthread.php 文件),則會給該主題的查看數加 1,這個動作在
viewthread_updateviews 這個函數 (forum_viewthread.php 文件的 695
行附近) 中進行。如果沒有開啓延遲更新,則會直接在 pre_forum_thread 表的對應的主題記錄中的 views
字段上加 1 。根據後台設置中的值 ($_G['setting']['delayviewcount']
的值,請參照上述對應值的開啓關係) 可以看出,值為 1 和 3 時均代表開啓了主題瀏覽量的延遲更新,此時會進入延遲更新的流程。
延遲更新點擊數會在 data/cache 目錄下產生以 forum_threadviews 開頭的 .log
文件,所以服務器上必須賦予這個目錄可讀可寫的權限。每一個需要增加點擊數的主題的 tid 都會寫入這個文件中,並獨自佔一行,此時不會對
pre_forum_thread 表有任何寫操作,達到延遲更新的目的。
當任意一個用户訪問到主題瀏覽頁 (訪問 forum_viewthread.php 文件) 時,系統的時間戳的值的末尾兩位為 00
時,便會觸發將緩存的點擊數一次性更新進數據庫中。前面所講的系統的時間戳如果大家不理解不要緊,就理解為 00 等於 100 秒,即每隔 100
秒就會觸發一次更新,此處的 100 秒代表一個整點秒數的時間點,而不是時間間隔為 100 秒,所以
發更新必須在某一個時間點發生
,而不是過 100 秒必定會發生一次更新。
舉例:當前是午夜 00:00:00,100 秒之後是 00:01:40,則只有在 00:01:40
這一個時間點上有用户訪問主題頁面才會觸發更新,如果剛巧沒人訪問則不會觸發更新,便要等到下一個 100 秒後的時間點  00:03:20 的到來。
更新觸發後,會調用 function_misc.php 文件中的 updateviews 函數 (function_misc.php 文件的
299 行附近) 執行批量的更新,將所有主題緩存的點擊數一次性更新到數據庫中。此過程需要 rename
函數的支持
,所以要確保 data/cache 目錄可讀可寫,並且在
PHP 的配置文件 php.ini 中不能禁止此函數,即 disable_functions 後面沒有 rename 字樣。

三、附件下載量延遲更新的實際使用

涉及的文件:source/module/forum/forum_attachment.php
搜索關鍵字:updateviews

涉及的文件:source/function/function_misc.php
搜索關鍵字:function updateviews

附件下載量,在下載一個附件時 (訪問 forum_attachment.php 文件),則會給該附件的下載數加 1,這個動作在
updateviews 這個函數執行的周圍 (forum_attachment.php 文件的 178
行附近) 進行。如果沒有開啓延遲更新,則會直接在 pre_forum_attachment 表的對應的附件記錄中的 downloads
字段上加 1 。根據後台設置中的值 ($_G['setting']['delayviewcount']
的值,請參照上述對應值的開啓關係) 可以看出,值為 2 和 3 時均代表開啓了附件下載量的延遲更新,此時會進入延遲更新的流程。
延遲更新點擊數會在 data/cache 目錄下產生以 forum_attachviews 開頭的 .log
文件,所以服務器上必須賦予這個目錄可讀可寫的權限。每一個需要增加下載量的附件的 aid 都會寫入這個文件中,並獨自佔一行,此時不會對
pre_forum_attachment 表有任何寫操作,達到延遲更新的目的。
當任意一個用户下載附件 (訪問 forum_attachment.php 文件) 時,系統的時間戳的值的末尾一位為 0
時,便會觸發將緩存的下載量一次性更新進數據庫中。前面所講的系統的時間戳如果大家不理解不要緊,就理解為 0 等於 10 秒,即每隔 10
秒就會觸發一次更新,此處的 10 秒代表一個整點秒數的時間點,而不是時間間隔為 10 秒,所以觸發更新必須在某一個時間點發生,而不是過 10
秒必定會發生一次更新。
舉例:當前是午夜 00:00:00,10 秒之後是 00:00:10,則只有在 00:00:10
這一個時間點上有用户去下載一個附件才會觸發更新,如果剛巧沒人下載則不會觸發更新,便要等到下一個 10 秒後的時間點  00:00:20 的到來。
更新觸發後,會調用 function_misc.php 文件中的 updateviews 函數 (function_misc.php 文件的
299 行附近) 執行批量的更新,將所有主題緩存的點擊數一次性更新到數據庫中。此過程需要 rename 函數的支持,所以要確保
data/cache 目錄可讀可寫,並且在 PHP 的配置文件 php.ini 中不能禁止此函數,即 disable_functions
後面沒有 rename 字樣。