相信很多人都看过DISCUZ源程序分析了.在DISCUZ的官方论坛上也可以找到相关帖子. 这几天看PHPCMS的代码,顺便写了点注释(不知道有人写过没有).有错的地方请大家指正.. 相比之下,discuz有内建的session系统,PHPCMS的这个commin.inc.php文件要简单得多. PSHPCMS现在已经开源了,global.fun.php 函数库中的函数现在官方都有说明.. http://dev.phpcms.cn/function/ PHP: <?php $mtime = explode(' ', microtime()); $phpcms_starttime = $mtime[1] + $mtime[0]; //$mtime[0] 为微秒 $mtime[1]为UNIX时间戳 //DEBUG 用的程序开始时间 unset($LANG, $_REQUEST, $HTTP_ENV_VARS, $HTTP_POST_VARS, $HTTP_GET_VARS, $HTTP_POST_FILES, $HTTP_COOKIE_VARS); //销毁一些不用的服务器变量 set_magic_quotes_runtime(0); //设置运行时的模式应用 define('IN_PHPCMS', TRUE); //定义常量IN_PHPCMS define('PHPCMS_ROOT', str_replace("\\", '/', substr(dirname(__FILE__), 0, -8))); //定义PHPCMS的路径,,,,,磁盘绝对路径! require PHPCMS_ROOT.'/config.inc.php'; require PHPCMS_ROOT.'/languages/'.$CONFIG['language'].'/phpcms.lang.php'; require PHPCMS_ROOT.'/include/global.func.php'; //引入 配置文件 语言文件 全局函数库! define('PHPCMS_PATH', $CONFIG['rootpath']); //定义系统路径 value = /phpcms/ define('PHPCMS_CACHEDIR', $CONFIG['cachedir']); //value=PHPCMS_ROOT.'/data/cache/'; //总缓冲目录 // $CONFIG['enablephplog'] ? set_error_handler('phpcms_error') : error_reporting(E_ERROR | E_WARNING | E_PARSE); $CONFIG['enablephplog'] ? set_error_handler('phpcms_error') : error_reporting(E_ALL); //是否启用php错误日志,如果启用就用自定义的异常处理函数,如果为关闭就设置错误报告级别...错误,警告,和语法错误! if($CONFIG['sessionsavepath']) session_save_path($CONFIG['sessionsavepath']); //设置会话保存目录 session_start(); //会话开始 if(function_exists('date_default_timezone_set')) date_default_timezone_set($CONFIG['timezone']); //设置时区 header('Content-type: text/html; charset='.$CONFIG['charset']); //设置输出字符集 if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) { $PHP_IP = getenv('HTTP_CLIENT_IP'); } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) { $PHP_IP = getenv('HTTP_X_FORWARDED_FOR'); } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) { $PHP_IP = getenv('REMOTE_ADDR'); } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) { $PHP_IP = $_SERVER['REMOTE_ADDR']; } preg_match("/[\d\.]{7,15}/", $PHP_IP, $ipmatches); $PHP_IP = $ipmatches[0] ? $ipmatches[0] : 'unknown'; //获取客户端IP $PHP_TIME = time(); //获得当前时间UNIX时间戳 $PHP_SELF = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : (isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : $_SERVER['ORIG_PATH_INFO']); //获得自己脚本的文件名 如: /test.php $PHP_QUERYSTRING = $_SERVER['QUERY_STRING']; // 获得查询字符串 也就是 xxx.php?4982394 问号后面的内容. $PHP_DOMAIN = $_SERVER['SERVER_NAME']; //获得服务器的域名 不包括 http:// $PHP_REFERER = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; //链接到当前页面的前一页面的 URL 地址。不是所有的用户代理(浏览器)都会设置这个变量,而且有的还可以手工修改 HTTP_REFERER。因此,这个变量不总是正确真实的。 $PHP_SCHEME = $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://'; // 获得http端口 $PHP_PORT = $_SERVER['SERVER_PORT'] == '80' ? '' : ':'.$_SERVER['SERVER_PORT']; //同上 $PHP_SITEURL = $PHP_SCHEME.$PHP_DOMAIN.$PHP_PORT.PHPCMS_PATH; //得到完整的PHPCMS的URL地址 $PHP_URL = $PHP_SCHEME.$PHP_DOMAIN.$PHP_PORT.$PHP_SELF.($PHP_QUERYSTRING ? '?'.$PHP_QUERYSTRING : ''); //得到当前网页的URL地址 $db_file = $db_class = 'db_'.$CONFIG['database']; //value=db_mysql if(!defined('IN_ADMIN')) //define('IN_ADMIN', TRUE); 这个定义在admin.php文件中 { if($CONFIG['dbiscache']) $db_file .= '_cache'; //value=db_mysql_cache if($CONFIG['phpcache'] == '2') { $cachefileid = md5($PHP_SELF.'?'.$PHP_QUERYSTRING); //cache文件ID MD5后的字符串 $cachefiledir = PHPCMS_ROOT.'/data/phpcache/'.substr($cachefileid, 0, 2).'/'; //cache文件目录 $cachefile = $cachefiledir.$cachefileid.'.html'; //CACHE文件 if(file_exists($cachefile) && ($PHP_TIME < @filemtime($cachefile) + $CONFIG['phpcacheexpires'])) //如果cache文件存在并且时间小于系统设置的CACHE文件过期时间,执行下面的语句 { require $cachefile; //引入cache文件 exit; //程序退出 } } if($PHP_QUERYSTRING && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", $PHP_QUERYSTRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); } $search_arr = array("/ union /i","/ select /i","/ update /i","/ outfile /i","/ or /i"); //需要替换的字符串数组 $replace_arr = array(' union ',' select ',' update ',' outfile ',' or '); //用来替换的字符串数组 $_POST = strip_sql($_POST); $_GET = strip_sql($_GET); $_COOKIE = strip_sql($_COOKIE); //整理POST数组 .主要是过滤SQL 语句中的一些特殊字符 unset($search_arr, $replace_arr); //注销不用的变量 } $magic_quotes_gpc = get_magic_quotes_gpc(); if(!$magic_quotes_gpc) { $_POST = new_addslashes($_POST); $_GET = new_addslashes($_GET); } //过滤GET 和POST数组中的数据 @extract($_POST, EXTR_SKIP); @extract($_GET, EXTR_SKIP); //展开数组$_POST $_GET unset($_POST, $_GET); //注销掉不用的变量 require PHPCMS_ROOT.'/include/'.$db_file.'.class.php'; //数据库操作类 require PHPCMS_ROOT.'/include/tag.func.php';// 标签函数库? require PHPCMS_ROOT.'/include/extension.inc.php'; //扩展函数库,用户自己定义的函数可以写在这里. $db = new $db_class; //建立数据库操作实例 $db->connect($CONFIG['dbhost'], $CONFIG['dbuser'], $CONFIG['dbpw'], $CONFIG['dbname'], $CONFIG['pconnect']); //建立数据库连接 $db->iscache = $CONFIG['dbiscache']; //是否CACHE $db->expires = $CONFIG['dbexpires']; //SQL连接过期时间 if(!cache_read('table.php')) //读缓存失败 { require_once PHPCMS_ROOT.'/include/cache.func.php'; //引入CACHE函数库 cache_all(); // 载入全部缓存 } $CACHE = cache_read('common.php');//共用CACHE数组赋值给变量 $CACHE $MODULE = $CACHE['module']; //模块CACHE $CHANNEL = $CACHE['channel'];//频道CACHE $PHPCMS = $CACHE['phpcms']; //系统CACHE $FIELD = $CACHE['field']; //? unset($CACHE, $ipmatches, $CONFIG['timezone'], $CONFIG['cachedir'], $CONFIG['dbhost'], $CONFIG['dbuser'], $CONFIG['dbpw'], $CONFIG['pconnect'], $CONFIG['dbiscache'], $CONFIG['dbexpires']); //注销不用的变量 if($PHPCMS['enablebanip'] && ip_banned($PHP_IP)) showmessage($LANG['administrator_banned_this_IP']); //如果客户端IP在阻止IP范围内,程序终止,显示错误信息! $TEMP = $MOD = $CHA = $CATEGORY = $CAT = array();//初始化一些变量为空数组 $ftp = $enableftp = $tags = $html = 0;//初始化变量为 空数组 if(!isset($mod)) { $mod = 'phpcms'; } elseif($mod != 'phpcms') { isset($MODULE[$mod]) or exit($LANG['module_not_exists']); $MOD = cache_read($mod.'_setting.php'); @include PHPCMS_ROOT.'/languages/'.(defined('IN_ADMIN') ? $CONFIG['adminlanguage'].'/'.$mod.'_admin.lang.php' : $CONFIG['language'].'/'.$mod.'.lang.php'); } //以上是检测系统启用了那些模块,根据系统设置情况 进行加载. if(!isset($forward)) $forward = $PHP_REFERER;//获得来路 $dosubmit = isset($dosubmit) ? 1 : 0; // $channelid = isset($channelid) ? intval($channelid) : 0; //频道ID,如果有设置,就取设置的值,没有就初始化为0; $skindir = PHPCMS_PATH.'templates/'.$CONFIG['defaulttemplate'].'/skins/'.$CONFIG['defaultskin']; //获得皮肤目录 if($PHPCMS['enablegzip'] && function_exists('ob_gzhandler')) { ($CONFIG['phpcache'] || defined('SHOWJS')) ? ob_start() : ob_start('ob_gzhandler'); } else { $PHPCMS['enablegzip'] = 0; ob_start(); } //是否启用压缩传输, $_userid = 0; //初始化用户ID $_username = '';//初始化用户名 $_groupid = 3;//初始化用户组 $_arrgroupid = array();////初始化扩展用户组数组为空数组; $phpcms_auth = getcookie('auth'); //取得索引为auth 的COOKIE值 失败返回FALSE; if($phpcms_auth) { $phpcms_auth_key = md5($PHPCMS['authkey'].$_SERVER['HTTP_USER_AGENT']); //phpcms认证码 list($_userid, $_password, $_answer) = $phpcms_auth ? explode("\t", phpcms_auth($phpcms_auth, 'DECODE')) : array(0, '', ''); //用解密后的phpcms_auth分别给userid pw answer 赋值,如果$phpcms_auth为 FALSE 则赋值为 0 空 空 $_userid = intval($_userid); if($_userid < 0) $_userid = 0; if($_userid) //如果userid TURE { $memberinfo = $db->get_one("SELECT username,password,groupid,arrgroupid,email,chargetype,begindate,enddate,money,point,credit,newmessages FROM ".TABLE_MEMBER." WHERE userid=$_userid LIMIT 0,1"); //根据$_userid 查询数据库 取得所属用户的一些基本信息 if($memberinfo && $memberinfo['password'] == $_password) { if($memberinfo['groupid'] == 2)//如果用户组为2,既是禁止用户 { mkcookie('auth', ''); //设置COOKIE showmessage($LANG['userid_banned_by_administrator']); //显示错误信息,该用户被禁用 } @extract($memberinfo, EXTR_PREFIX_ALL, ''); //展开会员信息数组, unset($memberinfo, $_password, $_answer); $_arrgroupid = $_arrgroupid ? array_filter(explode(',', $_arrgroupid)) : array(); //取得 扩展会员组ID } else { mkcookie('auth', ''); } } } unset($db_class, $db_file, $phpcms_auth, $phpcms_auth_key, $memberinfo); //注销不用的变量 ?>
真是好东西!不过有一句我还是不清楚: $PHP_QUERYSTRING = $_SERVER['QUERY_STRING']; // 获得查询字符串 也就是 xxx.php?4982394 问号后面的内容. 请问: 1、$_SERVER['QUERY_STRING']的值从哪儿来的? 2、好像这一条是与“推广奖励”代码条有关,如:http://www.chinahtml.com/bill/?83667,它是通过那个函数或语句传给$_SERVER['QUERY_STRING'],即当点击http://www.chinahtml.com/bill/?83667 时程序是如何运行的?是怎样提取83667的?