• phpcms 源码分析五:文件缓存实现


      这次是逆雪寒的文件缓存实现代码分析:

      

      1         /*
      2         [/php]
      3         
      4         PHPCMS的文本缓存实现:
      5         
      6         [php] 
      7         <?php 
      8         
      9         /*
     10         这个文件里面全是有关生成文本缓存的函数。文本缓存是个好东西。一般的项目,我们用不着内存缓存 : memcached  ,文本搞定。
     11         原理是这样的: 我们在后台是不是可以设置很多有关网站的参数。而这些参数很多都是固定的。就不变化的。都存到咱的数据库上。而我们程序那里呢
     12         每次都要访问数据库读出参数来进行我们程序中的操作。首先数据库查询是个很耗硬盘IO资源的一个东西,所以文本缓存刚好能减轻数据库那边的承重。
     13         我们在程序开始就把数据库里面的配置都转化为数组 等  放到  php文件里面。这样我们可以直接访问php文件而不用每次都访问数据库了。  
     14         php文本缓存其实成了我们程序和数据库的一个中间件。 所以我们自己写自己的文本缓存的时候其实要实现的很简单:  
     15         读数据库  ->  写到PHP文件 ->  程序中include ;来吧。开始文本缓存学习 
     16         */
     17         
     18         defined('IN_PHPCMS') or exit('Access Denied');
     19         
     20         // 生成所有缓存的总操作函数
     21         function cache_all()  
     22         {
     23             // 生成所有的数据库表名,表名是根据数据库里面当前的表名而生成。请看这个函数的详细分析
     24             cache_table();
     25              
     26             // 包含表常量
     27             require_once PHPCMS_CACHEDIR.'table.php'; 
     28             
     29             cache_common();
     30             
     31             cache_member_group();
     32             
     33             $modules = cache_module();
     34             
     35             $channelids = cache_channel(0);
     36             
     37             $keyids = array_merge($modules, $channelids);
     38             
     39             foreach($keyids as $keyid)
     40             {
     41                   $catids = cache_categorys($keyid);
     42                   
     43                   if(is_array($catids))
     44                   {
     45                        foreach($catids as $catid)
     46                        {
     47                         cache_category($catid);
     48                        }
     49                   }
     50             } 
     51             
     52             cache_type(0);
     53             
     54             return TRUE;
     55         }
     56         
     57         function cache_common()
     58         {
     59             global $db;
     60             
     61             // 查询所有能用的模块
     62             $query = $db->query("SELECT module,name,iscore,iscopy,isshare,moduledir,moduledomain FROM "
     63                                 .TABLE_MODULE." WHERE disabled=0"); 
     64             
     65             while($r = $db->fetch_array($query))
     66             {
     67                   $r['linkurl'] = '';
     68 
     69                   // 如果模块存在目录的就取它目录地址
     70                   if($r['module'] != 'phpcms' && $r['iscopy'] == 0) {
     71                       $r['linkurl'] = linkurl($r['moduledomain'] 
     72                                     ? dir_path($r['moduledomain']) 
     73                                     : $r['moduledir'].'/');
     74                   }
     75                   
     76                   unset($r['moduledomain']);
     77               
     78                   $key = $r['module'];
     79               
     80                   $data[$key] = $r; 
     81             }
     82             
     83             // 存到缓存数组,等一下一起把 $CACHE 数组写到文本里去
     84             $CACHE['module'] = $data; 
     85             
     86             $data = array();
     87             
     88             // 罗列能用的频道列表
     89             $query = $db->query("SELECT channelid, module, channelname, channeldir, channeldomain, 
     90                                  channelpic, introduce, style, islink, linkurl, cat_html_urlruleid, 
     91                                  item_html_urlruleid, special_html_urlruleid, cat_php_urlruleid, 
     92                                  item_php_urlruleid, special_php_urlruleid FROM ".TABLE_CHANNEL
     93                                  ." WHERE disabled=0 ORDER by listorder");
     94              
     95             while($r = $db->fetch_array($query))
     96             {
     97                   $r['linkurl'] = linkurl($r['linkurl']);
     98               
     99                   $key = $r['channelid'];
    100               
    101                   $data[$key] = $r;
    102             }
    103             
    104             // 存到缓存数组
    105             $CACHE['channel'] = $data;
    106              
    107             $data = array();
    108             
    109             // 查询 phpcms这个模块的设置信息,大家可以看下数据库这个表内容。setting 字段里面的信息是经过serialize 函数串行化的
    110             $r = $db->get_one("SELECT setting FROM ".TABLE_MODULE." WHERE module='phpcms'");
    111 
    112             /*
    113              * 所以取出的内容要unserialize 反串行.我是挺喜欢使用serialize 函数的。
    114              * 他可以实现把一个数组存到数据库或把一个对象存到数据库。或是拿来GET传递都行。
    115              * 太强了。大家可以试用下。可能你项目某个地方需要用到哦。
    116              */
    117             $CACHE['phpcms'] = unserialize($r['setting']);
    118             
    119             $fields = array();
    120             
    121             // 下载模块的信息,请自己看下这个表的数据就明白
    122             $result = $db->query("SELECT * FROM ".TABLE_FIELD." ORDER BY fieldid"); 
    123                 
    124             while($r = $db->fetch_array($result))
    125             {
    126                   $tablename = $r['tablename'];
    127               
    128                   $fields[$tablename] .= ','.$r['name'];
    129             }
    130             
    131             $CACHE['field'] = $fields;
    132             
    133             // 开始把$CACHE 数组写到 common.php 这个文本缓存里。大家可以自己去打开这个文件看下内容。一切了然
    134             cache_write('common.php', $CACHE); 
    135 
    136             return $CACHE;
    137         }
    138         
    139         // 更新文本缓存。最好在后台操作使用。因为PHP的文件flock 文件锁在某些平台使用不是很好。会出现多用户同写一个文件从而破坏缓存文件
    140         function cache_update($action = '')
    141         {
    142             global $db;
    143             
    144             $data=array();
    145             
    146             switch($action)
    147             {
    148                   case 'keylink':
    149                        $query=$db->query("SELECT linktext,linkurl FROM ".TABLE_KEYLINK." where passed=1");
    150                
    151                        while($r=$db->fetch_array($query))
    152                        {
    153                           $data[]=$r;
    154                        }
    155                   break;
    156                   
    157                   case 'reword':
    158                        $query = $db->query("SELECT word,replacement FROM ".TABLE_REWORD." where passed=1");
    159                        
    160                        while($r = $db->fetch_array($query))
    161                        {
    162                         $data[]=$r;
    163                        }
    164                   break;
    165                   
    166                   default:
    167                        $actions = array('keylink','reword');
    168                        
    169                        array_map('cache_update', $actions);
    170                        
    171                        return TRUE;
    172             }
    173             
    174             cache_write('cache_'.$action.'.php', $data);
    175             
    176             return $data;
    177         }
    178         
    179         function cache_table()
    180         {
    181             global $db,$CONFIG;
    182             
    183             /*
    184              显示数据库里面的所有表名
    185             */
    186             $query = $db->query("SHOW TABLES FROM `".$CONFIG['dbname']."`");
    187     
    188     
    189             while($r = $db->fetch_row($query))
    190             {
    191                   $table = $r[0];
    192               
    193                   // 寻找表前缀等于 $CONFIG['tablepre'] (在config.inc.php里设置) @@表前缀还有这个作用 嘿嘿
    194                   if(preg_match("/^".$CONFIG['tablepre']."/i", $table)) 
    195                   {
    196                        $tablename = str_replace($CONFIG['tablepre'], 'table_', $table);
    197                        
    198                        // $data['table_xx'] = xx; 形式   只能意会下了
    199                        $data[$tablename] = $table;    
    200                 }
    201             }
    202             
    203             // $db->free_result()  这个类方法其实是调用了函数:mysql_free_result() 函数 
    204             // 主要是为了清除数据库大量的查询而占用的内存。还是有必要的哦
    205             $db->free_result($query);
    206               
    207             // 常量 PHPCMS_CACHEDIR 在 common.inc.php 里面定义的。大家不记得了去看看吧。
    208             // 是存放phpcms 缓存目录的路径,这里意思是:如果缓存目录不存在
    209             if(!is_dir(PHPCMS_CACHEDIR)) 
    210             {
    211                 // 如果缓存目录不存在那么就创建
    212                   dir_create(PHPCMS_CACHEDIR);
    213                    
    214                   // 创建编译后的PHP模板目录,有关phpcms模板引擎编写。在下一章合适就开讲
    215                   dir_create($CONFIG['templatescachedir']); 
    216                   /*
    217                   dir_create() 函数为创建 目录函数。PHPCMS自己封装的,刚看了下。phpcms 挺强。
    218                   这个函数还可以通过ftp 来创建目录。这样就可以解决一些 开启了安全模式下的服务器对于创建目录等出现的问题
    219                   因为涉及到PHP FTP 知识。所以打算讲解到下面再说。
    220                   */
    221             }
    222 
    223             /*
    224              cache_write() 函数在global.func.php里面定义的。是把 已经从数据库取出来的数组信息写到 PHP文本上去。
    225              @@文本缓存关键的一步  废话少说上菜:
    226             */
    227             cache_write('table.php', $data , 'constant'); //很多朋友说找不到phpcms 表常量在那里定义的。就是在这里。
    228         
    229           function cache_write($file, $string, $type = 'array')
    230           {
    231                  // 检测 $string 内容是字符串的呢还是数组的,是数组的那就继续 ..
    232                if(is_array($string))
    233                {
    234                     $type = strtolower($type);
    235                       
    236                     // 然后再判断这个函数的模式标志 ,是否为数组模式,默认为数组模式
    237                     if($type == 'array')
    238                     {
    239                         /*这个太关键了。因为我们把数据库的信息写到文本上去的时候。是以符合PHP语法的格式写进去的。为什么呢?@@ 
    240                          * 十分废话,因为如果不是以PHP格式写到文件里面去,那么这个PHP文件怎么能给我们include 进程序运行调用呢? 
    241                          * 呵呵。 知道这一点就真的明白文本缓存的实现了。忒简单。 这里使用了个小技巧:使用了 var_export() 函数
    242                          * 这个函数会返回一个变量的字符串形式。这个函数太有帮助了。如果没有这个函数,我们还要自己想办法实现呢。
    243                          * 自己写一次文本缓存就明白了。会碰到这个问题的。 '
    ' 这个是文本文件的换行。初学者 别把<br> 和 '
    ' 搞混罗。 
    244                          * 一个是html 的 一个是文本文件的。
    245                          */
    246                         $string = "<?php
     return ".var_export($string,TRUE).";
    ?>"; 
    247                     }
    248                     
    249                     // 以内容形式
    250                     elseif($type == 'constant') 
    251                     {
    252                          $data='';
    253                          
    254                          foreach($string as $key => $value) $data .= "define('".strtoupper($key)."','".addslashes($value)."');
    ";
    255                          
    256                          // 如果以内容形式的话。就不是写数组到文本里面了。而是把内容都定义成常量。
    257                          $string = "<?php
    ".$data."
    ?>";
    258                     }
    259                    }
    260                
    261                    // file_put_contents()函数 是PHP5才支持的 效率最好。建议使用
    262                    $strlen = file_put_contents(PHPCMS_CACHEDIR.$file, $string);
    263                
    264                    // 设置目录 为可读可写可执行
    265                    chmod(PHPCMS_CACHEDIR.$file, 0777); 
    266                
    267                    // 返回写到文本的字节数
    268                    return $strlen; 
    269               }
    270               
    271             // 再说多一个读 缓存文件的操作函数  :上菜
    272               function cache_read($file, $mode = 'i')
    273               {
    274                   $cachefile = PHPCMS_CACHEDIR.$file;
    275             
    276                   if(!file_exists($cachefile)) {
    277                       return array();
    278                   }
    279             
    280                   return $mode == 'i' ? include $cachefile : file_get_contents($cachefile);
    281                }
    282           
    283                // 读缓存其实就是 include php 缓存文件。 讲完走人
    284     
    285                return $data;
    286         }
    287         /*
    288         phpcms 的所有数据库表名 都用根据数据库当前的表名来用常量来进行定义。我认为这样设计不是很好。
    289         不够灵活:比如如果我们更改数据库的一个表名的话。那么会出现找不到表的错误信息。
    290         而且想要修复还很麻烦。就是说不能随便更改表名了。不推荐大家这样写。我们可以把表名都定义在一个PHP文件里面。
    291         这样我们以后要改某个表名,就很方便了。
    292         */
    293 
    294         function cache_module($module = '')
    295         {
    296             global $db;
    297             if($module)
    298             {
    299                 // 模块具体信息
    300                   $r = $db->get_one("SELECT setting,module,name,iscopy,moduledir,moduledomain FROM "
    301                                     .TABLE_MODULE." WHERE module='$module'");
    302                    
    303                   if($r['setting'])
    304                   {
    305                       // 讲过了反串行。因为里面信息是串行化后再存到数据库的
    306                        $setting = unserialize($r['setting']); 
    307                   }
    308               
    309                   $setting['name'] = $r['name'];
    310               
    311                   $setting['moduledir'] = $r['moduledir'];
    312               
    313                   $setting['moduledomain'] = $r['moduledomain'];
    314               
    315                   $setting['linkurl'] = '';
    316               
    317                   if($r['module'] != 'phpcms' && $r['iscopy'] == 0)
    318                   {
    319                       $setting['linkurl'] = linkurl($r['moduledomain'] 
    320                                           ? dir_path($r['moduledomain']) 
    321                                           : $r['moduledir'].'/');
    322                         
    323                       cache_categorys($module);
    324                   }
    325               
    326                   unset($r['moduledomain']);
    327               
    328                   cache_write($module.'_setting.php', $setting);
    329               
    330                   return $setting;
    331             }
    332             
    333             else
    334             {
    335                   $query = $db->query("SELECT module FROM ".TABLE_MODULE
    336                                       ." WHERE disabled=0 ORDER by moduleid");
    337                   
    338                   while($r = $db->fetch_array($query))
    339                   {
    340                        cache_module($r['module']);
    341                        
    342                        $modules[] = $r['module'];
    343                 }
    344                 
    345                   return $modules;
    346             }
    347         }
    348         
    349         function cache_channel($channelid = 0)
    350         {
    351             global $db;
    352             
    353             if($channelid)
    354             {
    355                   $data = $db->get_one("SELECT * FROM ".TABLE_CHANNEL
    356                                        ." WHERE channelid=$channelid");
    357                   
    358                   if($data && !$data['islink'])
    359                   {
    360                        if($data['setting'])
    361                        {
    362                           $setting = unserialize($data['setting']);
    363                         unset($data['setting']);
    364                         $data = is_array($setting) ? array_merge($data, $setting) : $data;
    365                        }
    366                        
    367                        $data['linkurl'] = linkurl($data['linkurl']);
    368                        
    369                        cache_write('channel_'.$channelid.'.php', $data);
    370            
    371                        cache_categorys($channelid);
    372            
    373                        return $data;
    374                   }
    375             }
    376             
    377             else
    378             {
    379                   $query = $db->query("SELECT channelid FROM ".TABLE_CHANNEL
    380                                       ." WHERE islink=0 AND disabled=0 ORDER by channelid");
    381               
    382                 while($r = $db->fetch_array($query))
    383                   {
    384                       cache_channel($r['channelid']);
    385                
    386                       $channelids[] = $r['channelid'];
    387                   }
    388                   
    389                   return $channelids;
    390             }
    391         }
    392         
    393         function cache_categorys($keyid)
    394         {
    395             global $db, $PHPCMS, $CHANNEL;
    396             
    397             $urlpre = '';
    398             
    399             if(is_numeric($keyid)) 
    400             {
    401                   $keyid = intval($keyid);
    402               
    403                   $module = $CHANNEL[$keyid]['module'];
    404                     
    405                   $sql = " channelid=$keyid ";
    406             }
    407             
    408             else
    409             {
    410                     $sql = " module='$keyid' ";
    411             }
    412             
    413             $catids = $data = array();
    414                 
    415             $query = $db->query("SELECT module,channelid,catid,catname,style,introduce,catpic,islink,catdir,
    416                                  linkurl,parentid,arrparentid,parentdir,child,arrchildid,items,itemordertype,
    417                                  itemtarget,ismenu,islist,ishtml,htmldir,prefix,urlruleid,item_prefix,item_html_urlruleid,
    418                                  item_php_urlruleid FROM ".TABLE_CATEGORY." WHERE $sql ORDER by listorder,catid");
    419             
    420             while($r = $db->fetch_array($query))
    421             {
    422                   $r['linkurl'] = str_replace($PHPCMS['index'].'.'.$PHPCMS['fileext'], '', $r['linkurl']);
    423                  
    424                   $r['linkurl'] = $urlpre 
    425                                 ? preg_replace("|^".$urlpre."|", '', $r['linkurl']) 
    426                                 : linkurl($r['linkurl']);
    427               
    428                   $catid = $r['catid'];
    429                     
    430                   $data[$catid] = $r;
    431               
    432                   $catids[] = $catid;
    433             }
    434             
    435             // 写缓存罗。
    436             if($data) {
    437                 cache_write('categorys_'.$keyid.'.php', $data); 
    438             }
    439             
    440             return $catids;
    441         }
    442         
    443         function cache_category($catid)
    444         {
    445             global $db,$PHPCMS;
    446             
    447             if(!$catid) {
    448                 return FALSE;
    449             }
    450                 
    451             $data = $db->get_one("SELECT * FROM ".TABLE_CATEGORY
    452                                  ." WHERE catid=$catid");
    453             
    454             $setting = unserialize($data['setting']);
    455             
    456             unset($data['setting']);
    457             
    458             $data = is_array($setting) ? array_merge($data, $setting) : $data;
    459             
    460             $data['linkurl'] = linkurl(str_replace($PHPCMS['index'].'.'.$PHPCMS['fileext'], '', $data['linkurl']));
    461             
    462             cache_write('category_'.$catid.'.php', $data);
    463             
    464             return $data;
    465         }
    466         
    467         function cache_type($keyid=0)
    468         {
    469             global $db;
    470             
    471             if($keyid)
    472             {
    473                 $result = $db->query("SELECT * FROM ".TABLE_TYPE
    474                                      ." WHERE keyid='$keyid'");
    475                  $data = array();
    476                  
    477                  while($r = $db->fetch_array($result))
    478                  {
    479                        $r['introduce'] = $r['introduce']
    480                                        ? $r['introduce']
    481                                        : ' ';
    482               
    483                        $data[$r['typeid']] = $r;
    484                  }
    485                  
    486                  if($data)
    487                  {
    488                        cache_write('type_'.$keyid.'.php', $data);
    489                  }
    490               
    491                  return $data;
    492             }
    493             else 
    494             {
    495                   $modules = array();
    496               
    497                   $query = $db->query("SELECT module FROM ".TABLE_MODULE
    498                                       ." WHERE disabled=0 ORDER by moduleid");
    499                   
    500                   while($r = $db->fetch_array($query))
    501                   {
    502                        $modules[] = $r['module'];
    503                 }  
    504                   
    505                 $channelids = array();
    506                   
    507                 $query = $db->query("SELECT channelid FROM ".TABLE_CHANNEL
    508                                     ." WHERE islink=0 AND disabled=0 ORDER by channelid");
    509                   
    510                   while($r = $db->fetch_array($query))
    511                   {
    512                        $channelids[] = $r['channelid'];
    513                   }
    514               
    515                   $modulechannels = array_merge($modules, $channelids);
    516                   
    517                   foreach($modulechannels as $m)
    518                   {
    519                        $result = $db->query("SELECT * FROM ".TABLE_TYPE." WHERE keyid='$m'");
    520                        
    521                        $TYPE = array();
    522                        
    523                        while($r = $db->fetch_array($result))
    524                        {
    525                         $r['introduce'] = $r['introduce']? $r['introduce']:' ';
    526                     
    527                         $TYPE[$r['typeid']] = $r;
    528                        }
    529                
    530                        cache_write('type_'.$m.'.php',$TYPE);
    531                   }
    532 
    533                   return $modulechannels;  
    534             }
    535         }
    536         
    537         function cache_member_group()
    538         {
    539             global $db;
    540             
    541             // 用户组信息
    542             $query = $db->query("SELECT * FROM ".TABLE_MEMBER_GROUP." ORDER BY groupid"); 
    543             
    544             while($r = $db->fetch_array($query))
    545             {
    546                   $groupid = $r['groupid'];
    547                   cache_write('member_group_'.$groupid.'.php', $r);
    548                   $data[$groupid] = $r;
    549             }
    550             
    551             // 明白了吧。写缓存罗
    552             cache_write('member_group.php', $data); 
    553             
    554             return $data;
    555         }
    556         
    557         function cache_banip()
    558         {
    559             global $db, $PHP_TIME;
    560             
    561             $result = $db->query("SELECT ip,overtime FROM ".TABLE_BANIP
    562                                  ." WHERE ifban=1 and overtime>=$PHP_TIME order by id desc ");
    563             
    564             while($r = $db->fetch_array($result))
    565             {
    566                   $data[] = array('ip'=>$r['ip'],
    567                                   'overtime'=>$r['overtime']);
    568             }
    569             
    570             $db->free_result($result);
    571             
    572             cache_write('banip.php', $data);
    573             
    574             return $data;
    575         }
    576         

      

  • 相关阅读:
    【leetcode】对称二叉树
    【leetcode】判断回文数
    053686
    053685
    053684
    053683
    053682
    053681
    053680
    053477
  • 原文地址:https://www.cnblogs.com/thoupin/p/3345541.html
Copyright © 2020-2023  润新知