phpcms 源碼分析三:common.inc.php

  此次是逆雪寒分析common.inc.php的數據庫部分:php

  

  1 <?php
  2         // 包含數據庫操做類,下章詳說
  3         require PHPCMS_ROOT.'/include/'.$db_file.'.class.php';
  4          
  5         // 遇到再說 
  6         require PHPCMS_ROOT.'/include/tag.func.php';
  7           
  8         // 遇到再說  
  9         require PHPCMS_ROOT.'/include/extension.inc.php';
 10          
 11         // 實例化數據庫類 
 12         $db = new $db_class;
 13            
 14         // 鏈接數據庫@_@   
 15         $db->connect($CONFIG['dbhost'], 
 16                      $CONFIG['dbuser'], 
 17                      $CONFIG['dbpw'], 
 18                      $CONFIG['dbname'], 
 19                      $CONFIG['pconnect']);
 20          
 21         // 是否開啓SQL緩存
 22         $db->iscache = $CONFIG['dbiscache'];
 23          
 24         // 緩存時間 
 25         $db->expires = $CONFIG['dbexpires']; 
 26         
 27         if(!cache_read('table.php'))
 28         {
 29             require_once PHPCMS_ROOT.'/include/cache.func.php';
 30             
 31             cache_all(); //生成全部緩存
 32         }
 33         
 34         /*
 35         cache_read() 函數 讀緩存文件函數存在 global.func.php 裏面.上菜先:
 36         */
 37         /*
 38          就這麼簡單.文本緩存,在一些大的開源的PHP項目中常常見到.主要是爲了減輕數據庫的負荷的.
 39         好比在程序啓動文件裏面,就把一些後臺配置的經常使用信息緩存到php文件裏面.而後在之後的程序就能夠直接使用而不用每次都訪問數據庫了.
 40         但對常常要更新的信息.最好不要用文本緩存這形式,由於PHP文件內置的文件鎖flock()不是很好用.
 41         大系統中多用戶同時寫訪問的時候有可能會把緩存文件破壞.大系統建議使用 memcached  mysql5.1 分區  mysql 主從 來實現負載均衡 @=@ 
 42         廢話太多了. 這個函數很簡單.本身看下就明白了.若是緩存和模式變量 $mode 是否爲 i 是就include 不是就 把文件以字符串形式讀到內存中.
 43         若是 cache_read()找不到緩存文件'table.php'就會返回false,那麼就 加載 cache.func.php  文件.它裏面是些建立緩存的一些函數.
 44         而後呢執行 cache_all()函數生成全部的經常使用信息緩存.
 45         關於phpcms 的緩存更詳細包括生成原理.打算在弄完啓動文件common.inc.php 後再開篇寫個詳細的.  
 46         */
 47         function cache_read($file, $mode = 'i') // 'i' means 'include'
 48         {
 49             $cachefile = PHPCMS_CACHEDIR.$file;
 50             
 51             if(!file_exists($cachefile)) {
 52                 return array();
 53             }
 54             
 55             return $mode == 'i' ? (include $cachefile) : file_get_contents($cachefile);
 56         }
 57         
 58 
 59         /*
 60          加載 common.php 緩存文件裏面的變量(數據) 這樣咱們不用從數據庫讀了每次.是吧
 61         common.php 文件裏面是什麼來的呢?上菜:
 62         */
 63         $CACHE = cache_read('common.php'); 
 64         
 65 
 66         /*
 67          這個就是所有從數據庫裏面生成的文本緩存信息.咱們不用每次都鏈接數據庫讀數據庫.
 68         而只要訪問裏面的數組就能夠獲得一些配置信息.
 69         這個就是文本緩存的做用了,至於怎麼會生成這個文本緩存文件的.我會另外開一篇來介紹。
 70         */
 71         return array (
 72           'module' => 
 73           array (
 74             'phpcms' => 
 75             array (
 76               'module' => 'phpcms',
 77               'name' => 'phpcms',
 78               'iscore' => '1',
 79               'iscopy' => '0',
 80               'isshare' => '0',
 81               'moduledir' => '',
 82               'linkurl' => '',
 83             ),
 84             'member' => 
 85             array (
 86               'module' => 'member',
 87               'name' => '會員',
 88               'iscore' => '1',
 89               'iscopy' => '0',
 90               'isshare' => '0',
 91               'moduledir' => 'member',
 92               'linkurl' => '/phpcms/member/',
 93             ),
 94             'article' => 
 95             array (
 96               'module' => 'article',
 97               'name' => '文章',
 98               'iscore' => '0',
 99               'iscopy' => '1',
100               'isshare' => '0',
101               'moduledir' => 'article',
102               'linkurl' => '',
103             )));
104         
105 
106 
107         //緩存中的數據
108         $MODULE = $CACHE['module'];
109          
110         $CHANNEL = $CACHE['channel'];
111         
112         $PHPCMS = $CACHE['phpcms'];
113         
114         $FIELD = $CACHE['field'];
115 
116         /*
117          unset 掉不須要用的變量.
118         */
119         unset($CACHE, $ipmatches, $CONFIG['timezone'], $CONFIG['cachedir'], 
120               $CONFIG['dbhost'], $CONFIG['dbuser'], $CONFIG['dbpw'], 
121               $CONFIG['pconnect'], $CONFIG['dbiscache'], $CONFIG['dbexpires']);
122         
123 
124 
125         /*
126          $PHPCMS['enablebanip'] 是什麼.不用說應該知道了吧.這個就是後臺裏面設置是否開啓過濾IP訪問的功能.
127         (由於我沒用過phpcms,我是按照代碼猜的,不對的請指出)從這裏就看出了文本緩存也有他的做用的。 
128         ip_banned()函數是什麼呢.上菜再說:
129         */
130         if($PHPCMS['enablebanip'] && ip_banned($PHP_IP)) {
131             showmessage($LANG['administrator_banned_this_IP']);
132         }
133         
134 
135         /*
136          裏面也用到了 cache_read() 這個函數,仍是讀banip.php 這個文件.banip.php這個文件裏面存着你在後臺甚至的要過濾的IP列表.
137         裏面的邏輯比較簡單.本身消化下了.不明白跟帖問
138         showmessage() 函數是提示出錯信息封裝好的一個函數. 國家化的 $LANG['administrator_banned_this_IP']這個看到了吧.
139         這個就是讀語言包裏面的.這樣咱們就能夠出好多個語言版本的程序拉.
140         */
141         function ip_banned($ip)
142         {
143             // 前面定義過的.當前的時間
144             global $PHP_TIME; 
145             
146             $ipbanneds = cache_read('banip.php');
147             
148             if(!is_array($ipbanneds)) {
149                 return FALSE;
150             }
151             
152             foreach($ipbanneds as $v)
153             {
154                 if($v['overtime'] < $PHP_TIME) {
155                     return FALSE;
156                 }
157                 
158                 if($ip == $v['ip'] 
159                    || preg_match("/^" 
160                            . str_replace('.', '[.]', $v['ip'])."$/", $ip)) {
161                     return TRUE;
162                 }
163             }
164         }
165         
166 
167 
168         $TEMP = $MOD = $CHA = $CATEGORY = $CAT = array();
169         
170         $ftp = $enableftp = $tags = $html = 0;
171         
172         /*
173         初始化變量.這個是好習慣咱們要模仿.
174         */
175 
176         if(!isset($mod))
177         {
178             // phpcms 是默認加載的模塊
179             $mod = 'phpcms'; 
180         }
181         
182         elseif($mod != 'phpcms')
183         {
184             // 從緩存中讀加載的模塊是否開啓
185             isset($MODULE[$mod]) or exit($LANG['module_not_exists']); 
186             /*
187             這個寫法,我十分喜歡,平時也用.   xx && dd ; xx and dd  ;與運算要同時兩邊都爲真整個公式才爲真,就是利用這個原理. 
188             ; xx || dd ; xx or dd  或運算只要一個條件知足就不會執行下一個條件而繼續執行下去. 這樣寫是否是很酷.  
189             */
190     
191             // 開始加載這個模塊的一些經常使用配置數值。 phpcms 對應的每一個模塊都有一個緩存配置文件。@@ 怪不得速度那麼快
192             $MOD = cache_read($mod.'_setting.php'); 
193             
194             @include PHPCMS_ROOT.'/languages/'
195                           .(defined('IN_ADMIN') 
196                          ? $CONFIG['adminlanguage'].'/'.$mod.'_admin.lang.php' 
197                          : $CONFIG['language'].'/'.$mod.'.lang.php');
198             
199             /*
200             加載想對應的模塊語言包.
201             */
202         }
203         
204         // 記錄前一個URL地址。估計之後下面程序有須要用這個變量
205         if(!isset($forward)) {
206             $forward = $PHP_REFERER;
207         } 
208         
209         // 記錄是否有表單提交過.也是之後有用
210         $dosubmit = isset($dosubmit) ? 1 : 0;
211         
212         /*
213          * 記錄當前頻道的id  若是$channelid 沒有 isset 那麼就爲 0. 
214          * intval() 十分有用。數字和數字的比較加減速度會快不少。記得哦
215          */
216         $channelid = isset($channelid) ? intval($channelid) : 0;
217          
218         // 加載默認phpcms皮膚
219         $skindir = PHPCMS_PATH.'templates/' . $CONFIG['defaulttemplate']
220                  . '/skins/' . $CONFIG['defaultskin'];
221         
222         /*
223         $PHPCMS['enablegzip']   這個變量就是存在於 phpcms_setting.php 文件裏。下面已經說過了。
224         每一個模塊都有相對應的模塊配置緩存文件(是從數據庫copy過來的信息) 這個變量標緻 是否開啓 壓縮傳輸。
225         壓縮傳輸,聽名字就知道。就是把數據按照必定的算法壓縮小羅。而後再傳送到客戶端。這樣就能夠在有限的帶寬中傳輸更大的數據拉。
226         固然速度快了很多。壓縮的數據到了你的瀏覽器,它就自動解壓縮,老版本的一些瀏覽器不支持解壓縮哦。不過如今還有誰用好久的瀏覽器呢。
227         用法很簡單的:看下面就知道:首先判斷下,看客戶老大們是否在後臺選擇了這個模塊的壓縮傳輸
228         (若是是的話。天然的已經加載到了相對應的文本緩存文件裏面拉) 標緻:$PHPCMS['enablegzip']  和 判斷 回調函數 ob_gzhandler 是否開啓,  
229         ob_gzhandler 其實不算是個函數。看手冊說明。 就這麼簡單。它只是一個專門給 ob_start() 作回調使用的一個參數函數。
230         詳細請看下手冊。別偷懶哦,在程序開頭ob_start('ob_gzhandler')就算是開始壓縮傳輸了;判斷完了 若是爲真。就繼續下面的代碼:
231         
232         ($CONFIG['phpcache'] || defined('SHOWJS')) ? ob_start() : ob_start('ob_gzhandler');
233         看代碼phpcms 是這樣的: 若是用戶在後臺開啓了壓縮傳輸。而用戶又開啓了 頁面緩存。那麼就默認不使用壓縮傳輸了。我也不知道爲何這樣設計。
234         我測試了下。後臺開啓壓縮傳輸。又同時又使用頁面緩存。沒發現有什麼問題。@@
235         若是沒開啓壓縮傳輸,那麼咱們就ob_start(); 使用session 以前必需要 ob_start() ; 
236         並且在ob_start() 以前不能有任何的 頭文件發送和輸出。好比:echo header等要不會出錯的哦。
237         */
238         if($PHPCMS['enablegzip'] && function_exists('ob_gzhandler'))
239         {
240             ($CONFIG['phpcache'] || defined('SHOWJS')) ? ob_start() : ob_start('ob_gzhandler');
241         }
242         else
243         {
244             $PHPCMS['enablegzip'] = 0;
245             
246             ob_start();
247         }
248 
249         /*
250          $_userid,$_username,$_groupid  這幾個記錄用戶信息的變量初始化,不初始化危險就太大了。
251          @@ 若是給人家$_GET一個 _userid 變量過來。那麼就會把咱們這個變量覆蓋。可是咱們若是給這幾個變量一個值,
252         那麼按照就近原則。就算你GET個變量過來。你也同樣改不了我原來的變量值。你們好好本身想下。就會明白了。
253         getcookie() 這個自定義函數在 global.func.php文件裏定義的。上菜:
254         */
255         function getcookie($var)
256         {
257             global $CONFIG;
258             
259             $var = $CONFIG['cookiepre'].$var;
260             
261             return isset($_COOKIE[$var]) ? $_COOKIE[$var] : FALSE;
262         }
263         
264         /*
265         這個函數用來提取咱們設置的cookie 值. $CONFIG['cookiepre']  在 config.inc.php 文件裏面設置,cookie 名的前綴.  函數很簡單。一看就明白不說了。
266         */
267         $_userid = 0;
268          
269         $_username = '';
270         
271         $_groupid = 3;
272         
273         $_arrgroupid = array();
274         
275         $phpcms_auth = getcookie('auth');
276         
277 
278 
279         /*
280         list() = array(); 用戶你們本身試下。 意會下
281         phpcms_auth()  是加密和解密 函數,  由於cookie 是存在於客戶端。十分危險呀。
282         你看連用戶的密碼也存在cookie 不加密能行嗎。可是呢加密後又要能解密。由於用戶名和用戶密碼咱們往下操做要獲取的。 \
283         這個函數存在於 global.func.php 文件裏面。你們想了解這個算法的本身去看下吧。挺簡單的。 
284         其實就是圍繞着  $phpcms_auth_key  這個變量來加密解密和discuz 的cookie 機制差很少。
285         $phpcms_auth_key = md5($PHPCMS['authkey'].$_SERVER['HTTP_USER_AGENT']);  
286         看$PHPCMS['authkey'],估計後臺有個 cookie 加密值讓你填,而後以這個值和 $_SERVER['HTTP_USER_AGENT'](系統信息)
287         */
288         if($phpcms_auth)
289         {
290             $phpcms_auth_key = md5($PHPCMS['authkey'].$_SERVER['HTTP_USER_AGENT']);
291             
292             list($_userid, $_password, $_answer) = $phpcms_auth 
293                                                  ? explode("\t", phpcms_auth($phpcms_auth, 'DECODE')) 
294                                                  : array(0, '', '');
295 
296             $_userid = intval($_userid);
297             
298             if($_userid < 0) {
299                 // 讀出的cookie 的用戶id 若是是 小於0
300                 $_userid = 0; 
301             }
302             
303             // 若是 cookie 保存的這個uid 存在,那麼開始按照這個ID來查數據庫用戶表 來取出用戶信息
304             if($_userid) 
305             {
306                 /*
307                  phpcms 封裝好的數據庫類,下篇開講這個你們就大概看行了。
308                 你們看下 select  sql語句。 也能夠學習下。 首先最好不要使用 select * from xx  的 * 形式,除非你想獲取全部字段的記錄。
309                 只羅列你要的字段。這樣在數據量大的查詢中。速度明顯上去。
310                 常量: TABLE_MEMBER  定義了表名。這樣作有什麼好處呢?想都知道了,爲了之後變動表名方便而定義爲常量。
311                 這個東西那裏來的。估計在一個文件裏面定義好的。遇到了再講吧懶得找了。
312                 */
313                 $memberinfo = $db->get_one(
314                         "SELECT username,password,groupid,arrgroupid,email,chargetype,
315                          begindate,enddate,money,point,credit,newmessages FROM "
316                         .TABLE_MEMBER." WHERE userid=$_userid LIMIT 0,1");
317 
318                 // 用查詢出來的密碼和 cookie 中存在的密碼想對比.爲了在效率: 在比較前 先判斷查詢是否成功先。不少phper每每忽略。
319                 
320                 /*
321                  通過下面的讀cookie 和查數據庫用戶信息後。當肯定這個用戶信息是合法之後。就會自動登錄了。好比phpchina論壇。
322                  當你登錄後沒註銷。下次訪問的時候仍是登錄狀態。就是這個原理。記得模仿哦
323                  這裏詳細解釋下 mkcookie ()函數  上菜:
324                 */
325                 
326                 /*
327                 $time  爲cookie 的存活時間:  若是爲 0  就是關閉瀏覽器 cookie 就自動失效 ,  
328                 $PHP_TIME 在前面定義了:當前時間。   $PHP_TIME -3600  減去3600秒。就是一個小時前的意思,那確定是設置cookie 失效的意思了。
329                 $s  變量是 獲取 是否開啓SSL安全傳輸的標緻。 cookie 有一個參數是ssl傳輸的。若是服務器已經opensll 了那麼咱們確定不能浪費這麼好的安全資源了。
330                 $var cookie名的前綴,主要防止混淆。
331                 $CONFIG['cookiedomain']  這個傢伙在 config.inc.php裏面已經配置的了。定義爲: '/'   意思就是說 
332                 在當前域 的全部目錄的PHP程序都能訪問這個COOKIE ,還有限制目錄訪問COOKIE 的弄法。具體請看 setcookie () 函數手冊上說明。
333                 */
334                 function mkcookie($var, $value = '', $time = 0)
335                 {
336                     global $CONFIG,$PHP_TIME;
337                     
338                     $time = $time > 0 
339                           ? $time 
340                           : (empty($value) 
341                                     ? $PHP_TIME - 3600 
342                                     : 0);
343                     
344                     $s = $_SERVER['SERVER_PORT'] == '443' ? 1 : 0;
345                     
346                     $var = $CONFIG['cookiepre'].$var;
347                     
348                     return setcookie($var, $value, $time, $CONFIG['cookiepath'], $CONFIG['cookiedomain'], $s);
349                 }
350                 
351                 
352                 if($memberinfo && $memberinfo['password'] == $_password)  
353                   {
354                       // 若是用戶屬於的組的ID 爲 2  那麼這個用戶是被管理員禁止訪問的了。
355                        if($memberinfo['groupid'] == 2)  
356                        {
357                            // 清除cookie
358                         mkcookie('auth', ''); 
359                         
360                         // 提示出錯菜單
361                         showmessage($LANG['userid_banned_by_administrator']); 
362                        }
363                        
364                        //又來這招,應該明白了吧各位老大:把字段 變成 咱們能直接使用的變量
365                       @extract($memberinfo, EXTR_PREFIX_ALL, ''); 
366            
367                       unset($memberinfo, $_password, $_answer);
368            
369                       // 把字段爲 arrgroupid  值爲 FALSE 過濾掉。array_filter()不帶回調參數的用法,請看手冊。
370                       $_arrgroupid = $_arrgroupid ? array_filter(explode(',', $_arrgroupid)) : array();  
371                   }
372                   else
373                   {
374                     mkcookie('auth', '');
375                   }
376             }
377         }
378         
379         unset($db_class, $db_file, $phpcms_auth, $phpcms_auth_key, $memberinfo);
380          
381         /*        
382         下章我就分析 PHPCMS 的數據庫操做類文件和 PHPCMS的文本緩存機制.:victory: 但願你們繼續支持哦第一
383         
384         [ 本帖最後由 逆雪寒 於 2008-1-2 11:54 編輯 ]
385 
386 ?>
相關文章
相關標籤/搜索