PHP開源系統學習之fluxbb_1

lltong發表於2013-11-05

最近一直忙於做專案,雖說做了點新東西。感覺自己進步不是很大,總體水平還是跟半年前差不多,想到的東西跟以前差不多,寫出來的東西也跟以前差不多。只是現在做的東西多些,比以前敢做了。

近期準備利用點時間,讀讀一些開源系統,之前一直想學習下discuz,無奈多次放棄。還是對老外的感興趣,雖然自己英語差的不行,之前也做過wordpress的二次開發,這次準備對fluxbb下手。啥也不說了,直接上場。

整體結構是程式導向寫的,自己也喜歡這樣的風格,老外不少優秀的開源系統都是這樣的風格,wordpress也是。

在fluxbb中引入的檔案一般都省略“?>”結束

首先分析的是common.php及相關檔案(定義常量、引入函式庫、建立資料庫連線、環境檢查等)

//關閉魔術引用(如已開啟),php 5.2及以下預設開啟

//過濾POST、GET等,此處用到array_map(),如果是上傳檔案另做處理

 1 // Turn off magic_quotes_runtime
 2 if (get_magic_quotes_runtime())
 3     set_magic_quotes_runtime(0);
 4 
 5 // Strip slashes from GET/POST/COOKIE/REQUEST/FILES (if magic_quotes_gpc is enabled)
 6 if (!defined('FORUM_DISABLE_STRIPSLASHES') && get_magic_quotes_gpc())
 7 {
 8     function stripslashes_array($array)
 9     {
10         return is_array($array) ? array_map('stripslashes_array', $array) : stripslashes($array);
11     }
12 
13     $_GET = stripslashes_array($_GET);
14     $_POST = stripslashes_array($_POST);
15     $_COOKIE = stripslashes_array($_COOKIE);
16     $_REQUEST = stripslashes_array($_REQUEST);
17     if (is_array($_FILES))
18     {
19         // Don't strip valid slashes from tmp_name path on Windows
20         foreach ($_FILES AS $key => $value)
21             $_FILES[$key]['tmp_name'] = str_replace('\\', '\\\\', $value['tmp_name']);
22         $_FILES = stripslashes_array($_FILES);
23     }
24 }

//建立資料庫連線

1 // Load DB abstraction layer and connect
2 require PUN_ROOT.'include/dblayer/common_db.php';
3 
4 // Start a transaction
5 $db->start_transaction();

//common_db.php通過判斷$db_type來引入不同的db class,$db_type在根目錄下config.php檔案中已定義,common.php引入的config.php檔案

//這樣有個好處,以後換資料庫,操作起來方便,不過不同資料庫的sql語句語法不同,後期還是得改sql語句,fluxbb基本上直接用的是select * from ....

 1 // Load the appropriate DB layer class
 2 switch ($db_type)
 3 {
 4     case 'mysql':
 5         require_once PUN_ROOT.'include/dblayer/mysql.php';
 6         break;
 7 
 8     case 'mysql_innodb':
 9         require_once PUN_ROOT.'include/dblayer/mysql_innodb.php';
10         break;
11 
12     case 'mysqli':
13         require_once PUN_ROOT.'include/dblayer/mysqli.php';
14         break;
15 
16     case 'mysqli_innodb':
17         require_once PUN_ROOT.'include/dblayer/mysqli_innodb.php';
18         break;
19 
20     case 'pgsql':
21         require_once PUN_ROOT.'include/dblayer/pgsql.php';
22         break;
23 
24     case 'sqlite':
25         require_once PUN_ROOT.'include/dblayer/sqlite.php';
26         break;
27 
28     default:
29         error('\''.$db_type.'\' is not a valid database type. Please check settings in config.php.', __FILE__, __LINE__);
30         break;
31 }

//讀取cache_config.php配置檔案,避免重複查詢資料庫

//首先引入cache_config.php,常量PUN_CONFIG_LOADED其實在cache_config.php已有定義。如果沒定義的話,就重新生成檔案

 1 // Load cached config
 2 if (file_exists(FORUM_CACHE_DIR.'cache_config.php'))
 3     include FORUM_CACHE_DIR.'cache_config.php';
 4 
 5 if (!defined('PUN_CONFIG_LOADED'))
 6 {
 7     if (!defined('FORUM_CACHE_FUNCTIONS_LOADED'))
 8         require PUN_ROOT.'include/cache.php';
 9 
10     generate_config_cache();
11     require FORUM_CACHE_DIR.'cache_config.php';
12 }

//cache.php檔案

//從資料庫查取然後寫入到cache_config.php檔案中(前提是PUN_CONFIG_LOADED常量未定義)

//以下程式碼中有個函式用的很到位,var_export()跟var_dump()類似,不同的是前者返回一個串,後者直接輸出。C語言中printf()跟sprintf()的區別。

 1 //
 2 // Load some information about the latest registered users
 3 //
 4 function generate_users_info_cache()
 5 {
 6     global $db;
 7 
 8     $stats = array();
 9 
10     $result = $db->query('SELECT COUNT(id)-1 FROM '.$db->prefix.'users WHERE group_id!='.PUN_UNVERIFIED) or error('Unable to fetch total user count', __FILE__, __LINE__, $db->error());
11     $stats['total_users'] = $db->result($result);
12 
13     $result = $db->query('SELECT id, username FROM '.$db->prefix.'users WHERE group_id!='.PUN_UNVERIFIED.' ORDER BY registered DESC LIMIT 1') or error('Unable to fetch newest registered user', __FILE__, __LINE__, $db->error());
14     $stats['last_user'] = $db->fetch_assoc($result);
15 
16     // Output users info as PHP code
17     $content = '<?php'."\n\n".'define(\'PUN_USERS_INFO_LOADED\', 1);'."\n\n".'$stats = '.var_export($stats, true).';'."\n\n".'?>';
18     fluxbb_write_cache_file('cache_users_info.php', $content);
19 }

//寫入檔案

//考慮的比較全面,先flock()鎖定該檔案,然後ftruncate()清空,寫入fwrite(),後解鎖flock(),再關閉檔案流。

 1 //
 2 // Safely write out a cache file.
 3 //
 4 function fluxbb_write_cache_file($file, $content)
 5 {
 6     $fh = @fopen(FORUM_CACHE_DIR.$file, 'wb');
 7     if (!$fh)
 8         error('Unable to write cache file '.pun_htmlspecialchars($file).' to cache directory. Please make sure PHP has write access to the directory \''.pun_htmlspecialchars(FORUM_CACHE_DIR).'\'', __FILE__, __LINE__);
 9 
10     flock($fh, LOCK_EX);
11     ftruncate($fh, 0);
12 
13     fwrite($fh, $content);
14 
15     flock($fh, LOCK_UN);
16     fclose($fh);
17 
18     if (function_exists('apc_delete_file'))
19         @apc_delete_file(FORUM_CACHE_DIR.$file);
20 }

fluxbb在查詢函式中,一般是定義$db為全域性,$config為全域性。

//以下幾個函式主要是檢查使用者資訊及狀態,都在funcions.php中定義的

1 // Check/update/set cookie and fetch user info
2 $pun_user = array();
3 check_cookie($pun_user);    //傳引用
4 
5 // Check if current user is banned
6 check_bans();
7 
8 // Update online list
9 update_users_online();

//同讀取cache_config.php配置檔案,只是現在我還不知道這個是作什麼用的,以後再補上。資料庫表bans暫為空,寫入的cache_bans.php為一空陣列

 1 // Load cached bans
 2 if (file_exists(FORUM_CACHE_DIR.'cache_bans.php'))
 3     include FORUM_CACHE_DIR.'cache_bans.php';
 4 
 5 if (!defined('PUN_BANS_LOADED'))
 6 {
 7     if (!defined('FORUM_CACHE_FUNCTIONS_LOADED'))
 8         require PUN_ROOT.'include/cache.php';
 9 
10     generate_bans_cache();
11     require FORUM_CACHE_DIR.'cache_bans.php';
12 }

//extension_loaded()判斷擴充套件是否已匯入

1 if ($pun_config['o_gzip'] && extension_loaded('zlib'))
2         ob_start('ob_gzhandler');
3     else
4         ob_start();

 

common.php檔案基本是這些了。後續會作其他檔案或功能模組的簡單分析,備忘!

 補:剛在fluxbb一些涉及到資料庫的函式,都通過全域性變數$db_type來作判斷,然後分別寫不同的Sql語句,目前主要支援mysql和sqlite,特來贊一個!

 

原文作者:lltong,部落格園地址:http://www.cnblogs.com/lltong/

 

 

相關文章