最近一直忙于做项目,虽说做了点新东西。感觉自己进步不是很大,总体水平还是跟半年前差不多,想到的东西跟以前差不多,写出来的东西也跟以前差不多。只是现在做的东西多些,比以前敢做了。

近期准备利用点时间,读读一些开源系统,之前一直想学习下discuz,无奈多次放弃。还是对老外的感兴趣,虽然自己英语差的不行,之前也做过wordpress的二次开发,这次准备对fluxbb下手。啥也不说了,直接上场。

整体结构是面向过程写的,自己也喜欢这样的风格,老外不少优秀的开源系统都是这样的风格,wordpress也是。

在fluxbb中引入的文件一般都省略“?>”结束

首先分析的是common.php及相关文件(定义常量、引入函数库、建立数据库连接、环境检查等)

//关闭魔术引用(如已开启),php 5.2及以下默认开启

//过滤POST、GET等,此处用到array_map(),如果是上传文件另做处理

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

//建立数据库连接

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

//读取cache_config.php配置文件,避免重复查询数据库

//首先引入cache_config.php,常量PUN_CONFIG_LOADED其实在cache_config.php已有定义。如果没定义的话,就重新生成文件

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

//cache.php文件

//从数据库查取然后写入到cache_config.php文件中(前提是PUN_CONFIG_LOADED常量未定义)

//以下代码中有个函数用的很到位,var_export()跟var_dump()类似,不同的是前者返回一个串,后者直接输出。C语言中printf()跟sprintf()的区别。

  1. 1 //
  2. 2 // Load some information about the latest registered users
  3. 3 //
  4. 4 function generate_users_info_cache()
  5. 5 {
  6. 6 global $db;
  7. 7
  8. 8 $stats = array();
  9. 9
  10. 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. 11 $stats[\'total_users\'] = $db->result($result);
  12. 12
  13. 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. 14 $stats[\'last_user\'] = $db->fetch_assoc($result);
  15. 15
  16. 16 // Output users info as PHP code
  17. 17 $content = \'<?php\'."\n\n".\'define(\\'PUN_USERS_INFO_LOADED\\', 1);\'."\n\n".\'$stats = \'.var_export($stats, true).\';\'."\n\n".\'?>\';
  18. 18 fluxbb_write_cache_file(\'cache_users_info.php\', $content);
  19. 19 }

//写入文件

//考虑的比较全面,先flock()锁定该文件,然后ftruncate()清空,写入fwrite(),后解锁flock(),再关闭文件流。

  1. 1 //
  2. 2 // Safely write out a cache file.
  3. 3 //
  4. 4 function fluxbb_write_cache_file($file, $content)
  5. 5 {
  6. 6 $fh = @fopen(FORUM_CACHE_DIR.$file, \'wb\');
  7. 7 if (!$fh)
  8. 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. 9
  10. 10 flock($fh, LOCK_EX);
  11. 11 ftruncate($fh, 0);
  12. 12
  13. 13 fwrite($fh, $content);
  14. 14
  15. 15 flock($fh, LOCK_UN);
  16. 16 fclose($fh);
  17. 17
  18. 18 if (function_exists(\'apc_delete_file\'))
  19. 19 @apc_delete_file(FORUM_CACHE_DIR.$file);
  20. 20 }

fluxbb在查询函数中,一般是定义$db为全局,$config为全局。

//以下几个函数主要是检查用户信息及状态,都在funcions.php中定义的

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

//同读取cache_config.php配置文件,只是现在我还不知道这个是作什么用的,以后再补上。数据库表bans暂为空,写入的cache_bans.php为一空数组

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

//extension_loaded()判断扩展是否已导入

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

 

common.php文件基本是这些了。后续会作其他文件或功能模块的简单分析,备忘!

 补:刚在fluxbb一些涉及到数据库的函数,都通过全局变量$db_type来作判断,然后分别写不同的Sql语句,目前主要支持mysql和sqlite,特来赞一个!

 

原文作者:lltong,博客园地址:http://www.cnblogs.com/lltong/

 

 

版权声明:本文为lltong原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/lltong/p/3409553.html