最近一直忙於作項目,雖然說作了點新東西。感受本身進步不是很大,整體水平仍是跟半年前差很少,想到的東西跟之前差很少,寫出來的東西也跟之前差很少。只是如今作的東西多些,比之前敢作了。php
近期準備利用點時間,讀讀一些開源系統,以前一直想學習下discuz,無奈屢次放棄。仍是對老外的感興趣,雖然本身英語差的不行,以前也作過wordpress的二次開發,此次準備對fluxbb下手。啥也不說了,直接上場。html
總體結構是面向過程寫的,本身也喜歡這樣的風格,老外很多優秀的開源系統都是這樣的風格,wordpress也是。mysql
在fluxbb中引入的文件通常都省略「?>」結束sql
首先分析的是common.php及相關文件(定義常量、引入函數庫、創建數據庫鏈接、環境檢查等)數據庫
//關閉魔術引用(如已開啓),php 5.2及如下默認開啓數組
//過濾POST、GET等,此處用到array_map(),若是是上傳文件另作處理cookie
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 }
//創建數據庫鏈接app
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文件wordpress
//這樣有個好處,之後換數據庫,操做起來方便,不過不一樣數據庫的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/