cache.func.php文件详解- <?php/* [Discuz!] (C)2001-2009 Comsenz Inc. This is NOT a freeware, use is subject to license terms $Id: cache.func.php 21311 2009-11-26 01:35:43Z liulanbo $*/define('DISCUZ_KERNEL_VERSION', '7.2');define('DISCUZ_KERNEL_RELEASE', '20091126');function updatecache($cachename = '') { //分别引入 mysql操作库存,论坛名称,数据库前缀,最大论坛时间(估计是授权用户专用) global $db, $bbname, $tablepre, $maxbdays; //静态化一下数组,比如$cachename = setings 就读到这个数组 'settings' => array('settings'), static $cachescript = array ( 'settings' => array('settings'), 'forums' => array('forums'), 'icons' => array('icons'), 'stamps' => array('stamps'), 'ranks' => array('ranks'), 'usergroups' => array('usergroups'), 'request' => array('request'), 'medals' => array('medals'), 'magics' => array('magics'), 'topicadmin' => array('modreasons', 'stamptypeid'), 'archiver' => array('advs_archiver'), 'register' => array('advs_register', 'ipctrl'), 'faqs' => array('faqs'), 'secqaa' => array('secqaa'), 'censor' => array('censor'), 'ipbanned' => array('ipbanned'), 'smilies' => array('smilies_js'), 'forumstick' => array('forumstick'), 'index' => array('announcements', 'onlinelist', 'forumlinks', 'advs_index', 'heats'), 'forumdisplay' => array('smilies', 'announcements_forum', 'globalstick', 'forums', 'icons', 'onlinelist', 'advs_forumdisplay', 'forumstick'), 'viewthread' => array('smilies', 'smileytypes', 'forums', 'usergroups', 'ranks', 'stamps', 'bbcodes', 'smilies', 'advs_viewthread', 'tags_viewthread', 'custominfo', 'groupicon', 'focus', 'stamps'), 'post' => array('bbcodes_display', 'bbcodes', 'smileycodes', 'smilies', 'smileytypes', 'icons', 'domainwhitelist'), 'profilefields' => array('fields_required', 'fields_optional'), 'viewpro' => array('fields_required', 'fields_optional', 'custominfo'), 'bbcodes' => array('bbcodes', 'smilies', 'smileytypes'), ); //当最大时间有值时,就将在$cachescript 增加两段 if($maxbdays) { $cachescript['birthdays'] = array('birthdays'); $cachescript['index'][] = 'birthdays_index'; } // 组成更新数组. $updatelist = empty($cachename) ? array_values($cachescript) : (is_array($cachename) ? array('0' => $cachename) : array(array('0' => $cachename))); $updated = array(); // 现在循环. 由于是二维数组, 所以循环两次. foreach($updatelist as $value) { foreach($value as $cname) { //判断如果$updated数组为假,或者$updated中没有$cname的值,就进入, 目的是为了防止重复 if(empty($updated) || !in_array($cname, $updated)) { $updated[] = $cname; //进来一次, 就丢进数组, 以便循环中再次使用. getcachearray($cname); // 取得相应的值,并且生成缓存. } } } // 假如是空参数进入, 就对所有的缓存标识作判断. foreach($cachescript as $script => $cachenames) { if(empty($cachename) || (!is_array($cachename) && in_array($cachename, $cachenames)) || (is_array($cachename) && array_intersect($cachename, $cachenames))) { $cachedata = ''; $query = $db->query("SELECT data FROM {$tablepre}caches WHERE cachename in(".implodeids($cachenames).")"); while($data = $db->fetch_array($query)) { $cachedata .= $data['data']; } writetocache($script, $cachenames, $cachedata); } } //假如参数为空,或者参数为styles 就处理模板风格等缓存 if(!$cachename || $cachename == 'styles') { $stylevars = $styledata = $styleicons = array(); $defaultstyleid = $db->result_first("SELECT value FROM {$tablepre}settings WHERE variable = 'styleid'"); list(, $imagemaxwidth) = explode("\t", $db->result_first("SELECT value FROM {$tablepre}settings WHERE variable = 'zoomstatus'")); $imagemaxwidth = $imagemaxwidth ? $imagemaxwidth : 600; $imagemaxwidthint = intval($imagemaxwidth); $query = $db->query("SELECT sv.* FROM {$tablepre}stylevars sv LEFT JOIN {$tablepre}styles s ON s.styleid = sv.styleid AND (s.available=1 OR s.styleid='$defaultstyleid')"); while($var = $db->fetch_array($query)) { $stylevars[$var['styleid']][$var['variable']] = $var['substitute']; } $query = $db->query("SELECT s.*, t.directory AS tpldir FROM {$tablepre}styles s LEFT JOIN {$tablepre}templates t ON s.templateid=t.templateid WHERE s.available=1 OR s.styleid='$defaultstyleid'"); while($data = $db->fetch_array($query)) { $data = array_merge($data, $stylevars[$data['styleid']]); $datanew = array(); $data['imgdir'] = $data['imgdir'] ? $data['imgdir'] : 'images/default'; $data['styleimgdir'] = $data['styleimgdir'] ? $data['styleimgdir'] : $data['imgdir']; foreach($data as $k => $v) { if(substr($k, -7, 7) == 'bgcolor') { $newkey = substr($k, 0, -7).'bgcode'; $datanew[$newkey] = setcssbackground($data, $k); } } $data = array_merge($data, $datanew); $styleicons[$data['styleid']] = $data['menuhover']; if(strstr($data['boardimg'], ',')) { $flash = explode(",", $data['boardimg']); $flash[0] = trim($flash[0]); $flash[0] = preg_match('/^http:\/\//i', $flash[0]) ? $flash[0] : $data['styleimgdir'].'/'.$flash[0]; $data['boardlogo'] = "<embed src="".$flash[0]."" width="".trim($flash[1])."" height="".trim($flash[2])."" type="application/x-shockwave-flash" wmode="transparent"></embed>"; } else { $data['boardimg'] = preg_match('/^http:\/\//i', $data['boardimg']) ? $data['boardimg'] : $data['styleimgdir'].'/'.$data['boardimg']; $data['boardlogo'] = "<img src="$data[boardimg]" alt="$bbname" border="0" />"; } $data['bold'] = $data['nobold'] ? 'normal' : 'bold'; $contentwidthint = intval($data['contentwidth']); $contentwidthint = $contentwidthint ? $contentwidthint : 600; if(substr(trim($data['contentwidth']), -1, 1) != '%') { if(substr(trim($imagemaxwidth), -1, 1) != '%') { $data['imagemaxwidth'] = $imagemaxwidthint > $contentwidthint ? $contentwidthint : $imagemaxwidthint; } else { $data['imagemaxwidth'] = intval($contentwidthint * $imagemaxwidthint / 100); } } else { if(substr(trim($imagemaxwidth), -1, 1) != '%') { $data['imagemaxwidth'] = '%'.$imagemaxwidthint; } else { $data['imagemaxwidth'] = ($imagemaxwidthint > $contentwidthint ? $contentwidthint : $imagemaxwidthint).'%'; } } $data['verhash'] = random(3); $styledata[] = $data; } foreach($styledata as $data) { $data['styleicons'] = $styleicons; writetocache($data['styleid'], '', getcachevars($data, 'CONST'), 'style_'); writetocsscache($data); } } //假如参数为空,或者参数为usergroups 就处理用户组等缓存 if(!$cachename || $cachename == 'usergroups') { @include_once DISCUZ_ROOT.'forumdata/cache/cache_settings.php'; $threadplugins = !isset($_DCACHE['settings']) ? $GLOBALS['threadplugins'] : $_DCACHE['settings']; $allowthreadplugin = $threadplugins ? unserialize($db->result_first("SELECT value FROM {$tablepre}settings WHERE variable='allowthreadplugin'")) : array(); $query = $db->query("SELECT * FROM {$tablepre}usergroups u LEFT JOIN {$tablepre}admingroups a ON u.groupid=a.admingid"); while($data = $db->fetch_array($query)) { $ratearray = array(); if($data['raterange']) { foreach(explode("\n", $data['raterange']) as $rating) { $rating = explode("\t", $rating); $ratearray[$rating[0]] = array('min' => $rating[1], 'max' => $rating[2], 'mrpd' => $rating[3]); } } $data['raterange'] = $ratearray; $data['grouptitle'] = $data['color'] ? '<font color="'.$data['color'].'">'.$data['grouptitle'].'</font>' : $data['grouptitle']; $data['grouptype'] = $data['type']; $data['grouppublic'] = $data['system'] != 'private'; $data['groupcreditshigher'] = $data['creditshigher']; $data['groupcreditslower'] = $data['creditslower']; $data['allowthreadplugin'] = $threadplugins ? $allowthreadplugin[$data['groupid']] : array(); unset($data['type'], $data['system'], $data['creditshigher'], $data['creditslower'], $data['color'], $data['groupavatar'], $data['admingid']); writetocache($data['groupid'], '', getcachevars($data), 'usergroup_'); } } //假如参数为空,或者参数为admingroups 就处理管理用户组等缓存 if(!$cachename || $cachename == 'admingroups') { $query = $db->query("SELECT * FROM {$tablepre}admingroups"); while($data = $db->fetch_array($query)) { writetocache($data['admingid'], '', getcachevars($data), 'admingroup_'); } } if(!$cachename || $cachename == 'plugins') { $query = $db->query("SELECT pluginid, available, adminid, name, identifier, datatables, directory, copyright, modules FROM {$tablepre}plugins"); while($plugin = $db->fetch_array($query)) { $data = array_merge($plugin, array('modules' => array()), array('vars' => array())); $plugin['modules'] = unserialize($plugin['modules']); if(is_array($plugin['modules'])) { foreach($plugin['modules'] as $module) { $data['modules'][$module['name']] = $module; } } $queryvars = $db->query("SELECT variable, value FROM {$tablepre}pluginvars WHERE pluginid='$plugin[pluginid]'"); while($var = $db->fetch_array($queryvars)) { $data['vars'][$var['variable']] = $var['value']; } writetocache($plugin['identifier'], '', "\$_DPLUGIN['$plugin[identifier]'] = ".arrayeval($data), 'plugin_'); } } //假如参数为空,或者参数为threadsorts 就处理主题信息等缓存 if(!$cachename || $cachename == 'threadsorts') { $sortlist = $templatedata = array(); $query = $db->query("SELECT t.typeid AS sortid, tt.optionid, tt.title, tt.type, tt.unit, tt.rules, tt.identifier, tt.description, tv.required, tv.unchangeable, tv.search, tv.subjectshow FROM {$tablepre}threadtypes t LEFT JOIN {$tablepre}typevars tv ON t.typeid=tv.sortid LEFT JOIN {$tablepre}typeoptions tt ON tv.optionid=tt.optionid WHERE t.special='1' AND tv.available='1' ORDER BY tv.displayorder"); while($data = $db->fetch_array($query)) { $data['rules'] = unserialize($data['rules']); $sortid = $data['sortid']; $optionid = $data['optionid']; $sortlist[$sortid][$optionid] = array( 'title' => dhtmlspecialchars($data['title']), 'type' => dhtmlspecialchars($data['type']), 'unit' => dhtmlspecialchars($data['unit']), 'identifier' => dhtmlspecialchars($data['identifier']), 'description' => dhtmlspecialchars($data['description']), 'required' => intval($data['required']), 'unchangeable' => intval($data['unchangeable']), 'search' => intval($data['search']), 'subjectshow' => intval($data['subjectshow']), ); if(in_array($data['type'], array('select', 'checkbox', 'radio'))) { if($data['rules']['choices']) { $choices = array(); foreach(explode("\n", $data['rules']['choices']) as $item) { list($index, $choice) = explode('=', $item); $choices[trim($index)] = trim($choice); } $sortlist[$sortid][$optionid]['choices'] = $choices; } else { $typelist[$sortid][$optionid]['choices'] = array(); } } elseif(in_array($data['type'], array('text', 'textarea'))) { $sortlist[$sortid][$optionid]['maxlength'] = intval($data['rules']['maxlength']); } elseif($data['type'] == 'image') { $sortlist[$sortid][$optionid]['maxwidth'] = intval($data['rules']['maxwidth']); $sortlist[$sortid][$optionid]['maxheight'] = intval($data['rules']['maxheight']); } elseif($data['type'] == 'number') { $sortlist[$sortid][$optionid]['maxnum'] = intval($data['rules']['maxnum']); $sortlist[$sortid][$optionid]['minnum'] = intval($data['rules']['minnum']); } } $query = $db->query("SELECT typeid, description, template, stemplate FROM {$tablepre}threadtypes WHERE special='1'"); while($data = $db->fetch_array($query)) { $templatedata[$data['typeid']] = $data['template']; $stemplatedata[$data['typeid']] = $data['stemplate']; $threaddesc[$data['typeid']] = dhtmlspecialchars($data['description']); } foreach($sortlist as $sortid => $option) { writetocache($sortid, '', "\$_DTYPE = ".arrayeval($option).";\n\n\$_DTYPETEMPLATE = "".str_replace('"', '"', $templatedata[$sortid])."";\n\n\$_DSTYPETEMPLATE = "".str_replace('"', '"', $stemplatedata[$sortid])."";\n", 'threadsort_'); } }}// 这是css缓存文件生成需要的处理css背景颜色函数function setcssbackground(&$data, $code) { $codes = explode(' ', $data[$code]); $css = $codevalue = ''; for($i = 0; $i < count($codes); $i++) { if($i < 2) { if($codes[$i] != '') { if($codes[$i]{0} == '#') { $css .= strtoupper($codes[$i]).' '; $codevalue = strtoupper($codes[$i]); } elseif(preg_match('/^http:\/\//i', $codes[$i])) { $css .= 'url("'.$codes[$i].'") '; } else { $css .= 'url("'.$data['styleimgdir'].'/'.$codes[$i].'") '; } } } else { $css .= $codes[$i].' '; } } $data[$code] = $codevalue; $css = trim($css); return $css ? 'background: '.$css : '';}// 更新系统配置缓存function updatesettings() { global $_DCACHE; if(isset($_DCACHE['settings']) && is_array($_DCACHE['settings'])) { writetocache('settings', '', '$_DCACHE[\'settings\'] = '.arrayeval($_DCACHE['settings']).";\n\n"); }}// 写入缓存文件, 详解一下.function writetocache($script, $cachenames, $cachedata = '', $prefix = 'cache_') { global $authkey; //假如$cachenames是数组,并且$cachedata为假 if(is_array($cachenames) && !$cachedata) { foreach($cachenames as $name) { //赋予内置函数的指定标识, 即可有数据返回 $cachedata .= getcachearray($name, $script); } } $dir = DISCUZ_ROOT.'./forumdata/cache/'; //如果缓存目录不存在, 就生成一个. if(!is_dir($dir)) { @mkdir($dir, 0777); } if($fp = @fopen("$dir$prefix$script.php", 'wb')) { fwrite($fp, "<?php\n//Discuz! cache file, DO NOT modify me!". "\n//Created: ".date("M j, Y, G:i"). "\n//Identify: ".md5($prefix.$script.'.php'.$cachedata.$authkey)."\n\n$cachedata?>"); fclose($fp); } else { exit('Can not write to cache files, please check directory ./forumdata/ and ./forumdata/cache/ .'); }}// 更新css缓存生成过程中, 里面的路径问题, 参数为css.htm的内容.function writetocsscache($data) { $cssdata = ''; foreach(array('_common' => array('css_common', 'css_append'), '_special' => array('css_special', 'css_special_append'), '_wysiwyg' => array('css_wysiwyg', '_wysiwyg_append'), '_seditor' => array('css_seditor', 'css_seditor_append'), '_calendar' => array('css_calendar', 'css_calendar_append'), '_moderator' => array('css_moderator', 'css_moderator_append'), '_script' => array('css_script', 'css_script_append'), '_task_newbie' => array('css_task_newbie', 'css_task_newbie_append') ) as $extra => $cssfiles) { $cssdata = ''; foreach($cssfiles as $css) { $cssfile = DISCUZ_ROOT.'./'.$data['tpldir'].'/'.$css.'.htm'; !file_exists($cssfile) && $cssfile = DISCUZ_ROOT.'./templates/default/'.$css.'.htm'; if(file_exists($cssfile)) { $fp = fopen($cssfile, 'r'); $cssdata .= @fread($fp, filesize($cssfile))."\n\n"; fclose($fp); } } $cssdata = preg_replace("/\{([A-Z0-9]+)\}/e", '\$data[strtolower(\'\1\')]', $cssdata); $cssdata = preg_replace("/<\?.+?\?>\s*/", '', $cssdata); $cssdata = !preg_match('/^http:\/\//i', $data['styleimgdir']) ? str_replace("url("$data[styleimgdir]", "url("../../$data[styleimgdir]", $cssdata) : $cssdata; $cssdata = !preg_match('/^http:\/\//i', $data['styleimgdir']) ? str_replace("url($data[styleimgdir]", "url(../../$data[styleimgdir]", $cssdata) : $cssdata; $cssdata = !preg_match('/^http:\/\//i', $data['imgdir']) ? str_replace("url("$data[imgdir]", "url("../../$data[imgdir]", $cssdata) : $cssdata; $cssdata = !preg_match('/^http:\/\//i', $data['imgdir']) ? str_replace("url($data[imgdir]", "url(../../$data[imgdir]", $cssdata) : $cssdata; if($extra != '_script') { $cssdata = preg_replace(array('/\s*([,;:\{\}])\s*/', '/[\t\n\r]/', '/\/\*.+?\*\//'), array('\\1', '',''), $cssdata); } if(@$fp = fopen(DISCUZ_ROOT.'./forumdata/cache/style_'.$data['styleid'].$extra.'.css', 'w')) { fwrite($fp, $cssdata); fclose($fp); } else { exit('Can not write to cache files, please check directory ./forumdata/ and ./forumdata/cache/ .'); } }}// 将js文件复制到缓存目录.function writetojscache() { $dir = DISCUZ_ROOT.'include/js/'; $dh = opendir($dir); $remove = array( '/(^|\r|\n)\/\*.+?(\r|\n)\*\/(\r|\n)/is', '/\/\/note.+?(\r|\n)/i', '/\/\/debug.+?(\r|\n)/i', '/(^|\r|\n)(\s|\t)+/', '/(\r|\n)/', ); while(($entry = readdir($dh)) !== false) { if(fileext($entry) == 'js') { $jsfile = $dir.$entry; $fp = fopen($jsfile, 'r'); $jsdata = @fread($fp, filesize($jsfile)); fclose($fp); $jsdata = preg_replace($remove, '', $jsdata); if(@$fp = fopen(DISCUZ_ROOT.'./forumdata/cache/'.$entry, 'w')) { fwrite($fp, $jsdata); fclose($fp); } else { exit('Can not write to cache files, please check directory ./forumdata/ and ./forumdata/cache/ .'); } } }}//取得缓存数组, 内置. 标识名,及文件名.function getcachearray($cachename, $script = '') { global $db, $timestamp, $tablepre, $timeoffset, $maxbdays, $smcols, $smrows, $charset, $scriptlang; //省略上千代码.}//组成缓存文件需要的数据数组.function getcachevars($data, $type = 'VAR') { $evaluate = ''; foreach($data as $key => $val) { if(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $key)) { continue; } if(is_array($val)) { $evaluate .= "\$key = ".arrayeval($val).";\n"; } else { $val = addcslashes($val, '\'\\'); $evaluate .= $type == 'VAR' ? "\$key = '$val';\n" : "define('".strtoupper($key)."', '$val');\n"; } } return $evaluate;}//取得广告设置的内容数组.function advertisement($range) { global $db, $tablepre, $timestamp; $advs = array(); $query = $db->query("SELECT * FROM {$tablepre}advertisements WHERE available>'0' AND starttime<='$timestamp' ORDER BY displayorder"); if($db->num_rows($query)) { while($adv = $db->fetch_array($query)) { if(in_array($adv['type'], array('footerbanner', 'thread'))) { $parameters = unserialize($adv['parameters']); $position = isset($parameters['position']) && in_array($parameters['position'], array(2, 3)) ? $parameters['position'] : 1; $type = $adv['type'].$position; } else { $type = $adv['type']; } $adv['targets'] = in_array($adv['targets'], array('', 'all')) ? ($type == 'text' ? 'forum' : (substr($type, 0, 6) == 'thread' ? 'forum' : 'all')) : $adv['targets']; foreach(explode("\t", $adv['targets']) as $target) { if($range == 'index' && substr($target, 0, 3) == 'gid') { $advs['cat'][$type][substr($target, 3)][] = $adv['advid']; $advs['items'][$adv['advid']] = $adv['code']; } $target = $target == '0' || $type == 'intercat' ? 'index' : (in_array($target, array('all', 'index', 'forumdisplay', 'viewthread', 'register', 'redirect', 'archiver')) ? $target : ($target == 'forum' ? 'forum_all' : 'forum_'.$target)); if((($range == 'forumdisplay' && !in_array($adv['type'], array('thread', 'interthread'))) || $range == 'viewthread') && substr($target, 0, 6) == 'forum_') { if($adv['type'] == 'thread') { foreach(isset($parameters['displayorder']) ? explode("\t", $parameters['displayorder']) : array('0') as $postcount) { $advs['type'][$type.'_'.$postcount][$target][] = $adv['advid']; } } else { $advs['type'][$type][$target][] = $adv['advid']; } $advs['items'][$adv['advid']] = $adv['code']; } elseif($range == 'all' && in_array($target, array('all', 'redirect'))) { $advs[$target]['type'][$type][] = $adv['advid']; $advs[$target]['items'][$adv['advid']] = $adv['code']; } elseif($range == 'index' && $type == 'intercat') { $parameters = unserialize($adv['parameters']); foreach(is_array($parameters['position']) ? $parameters['position'] : array('0') as $position) { $advs['type'][$type][$position][] = $adv['advid']; $advs['items'][$adv['advid']] = $adv['code']; } } elseif($target == $range || ($range == 'index' && $target == 'forum_all' && $type == 'text')) { $advs['type'][$type][] = $adv['advid']; $advs['items'][$adv['advid']] = $adv['code']; } } } } return $advs;}// 简单判断.function pluginmodulecmp($a, $b) { return $a['displayorder'] > $b['displayorder'] ? 1 : -1;}// 计算长宽的函数function smthumb($size, $smthumb = 50) { if($size[0] <= $smthumb && $size[1] <= $smthumb) { return array('w' => $size[0], 'h' => $size[1]); } $sm = array(); $x_ratio = $smthumb / $size[0]; $y_ratio = $smthumb / $size[1]; if(($x_ratio * $size[1]) < $smthumb) { $sm['h'] = ceil($x_ratio * $size[1]); $sm['w'] = $smthumb; } else { $sm['w'] = ceil($y_ratio * $size[0]); $sm['h'] = $smthumb; } return $sm;}// 处理缓存生成时部分内容样式的解析function parsehighlight($highlight) { if($highlight) { $colorarray = array('', 'red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'purple', 'gray'); $string = sprintf('%02d', $highlight); $stylestr = sprintf('%03b', $string[0]); $style = ' style="'; $style .= $stylestr[0] ? 'font-weight: bold;' : ''; $style .= $stylestr[1] ? 'font-style: italic;' : ''; $style .= $stylestr[2] ? 'text-decoration: underline;' : ''; $style .= $string[1] ? 'color: '.$colorarray[$string[1]] : ''; $style .= '"'; } else { $style = ''; } return $style;}// 这就是传说的array的立体型输出.function arrayeval($array, $level = 0) { if(!is_array($array)) { return "'".$array."'"; } if(is_array($array) && function_exists('var_export')) { return var_export($array, true); } $space = ''; for($i = 0; $i <= $level; $i++) { $space .= "\t"; } $evaluate = "Array\n$space(\n"; $comma = $space; if(is_array($array)) { foreach($array as $key => $val) { $key = is_string($key) ? '\''.addcslashes($key, '\'\\').'\'' : $key; $val = !is_array($val) && (!preg_match("/^\-?[1-9]\d*$/", $val) || strlen($val) > 12) ? '\''.addcslashes($val, '\'\\').'\'' : $val; if(is_array($val)) { $evaluate .= "$comma$key => ".arrayeval($val, $level + 1); } else { $evaluate .= "$comma$key => $val"; } $comma = ",\n$space"; } } $evaluate .= "\n$space)"; return $evaluate;}?>
复制代码 |