zoukankan      html  css  js  c++  java
  • phpcms 源码分析三:common.inc.php

      这次是逆雪寒分析common.inc.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("	", 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 ?>
  • 相关阅读:
    PHP入门(二)
    PHP入门(一)
    TypeScript作为前端开发你必须学习的技能(三)
    东北师范大学-构建之法-20201022作业成绩
    20201108-东北师范大学-助教-周总结-第8次
    20201103-东北师范大学-助教-周总结-第7次
    东北师范大学-构建之法-20201015作业成绩
    20201026-东北师范大学-助教-周总结-第6次
    东北师范大学-构建之法-20201008作业成绩
    20201019-东北师范大学-助教-周总结-第5次
  • 原文地址:https://www.cnblogs.com/thoupin/p/3345534.html
Copyright © 2011-2022 走看看