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                          * 自己写一次文本缓存就明白了。会碰到这个问题的。 '\n' 这个是文本文件的换行。初学者 别把<br> 和 '\n' 搞混罗。 

244                          * 一个是html 的 一个是文本文件的。

245                          */

246                         $string = "<?php\n return ".var_export($string,TRUE).";\n?>"; 

247                     }

248                     

249                     // 以内容形式

250                     elseif($type == 'constant') 

251                     {

252                          $data='';

253                          

254                          foreach($string as $key => $value) $data .= "define('".strtoupper($key)."','".addslashes($value)."');\n";

255                          

256                          // 如果以内容形式的话。就不是写数组到文本里面了。而是把内容都定义成常量。

257                          $string = "<?php\n".$data."\n?>";

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         

 

  

你可能感兴趣的:(phpcms)