/** * Gets a test bucket value for the given seed */ public static function get($key, $seed = null) { self::initialize(); $seed = $seed ?: self::$_seed; $cacheKey = 'test_' . $key . '_' . $seed; return Cache::fetch(function () use($key, $seed) { $retVal = DEFAULT_TEST_VALUE; $found = false; if (isset(self::$_tests->{$key})) { $test = self::$_tests->{$key}; if (isset($test->whiteLists)) { foreach ($test->whiteLists as $whiteList) { if (in_array($seed, $whiteList->ids)) { $retVal = $whiteList->value; $found = true; break; } } } if (!$found && isset($test->ramps)) { srand($seed); $rand = rand() % 100; $percentTotal = 0; foreach ($test->ramps as $ramp) { $percentTotal += $ramp->percent; if ($rand <= $percentTotal) { $retVal = $ramp->value; break; } } } } return $retVal; }, $cacheKey); }
public static function generate(array $params) { $active = array_shift($params) !== 'past'; $brackets = Lib\Cache::fetch(function () use($active) { $allBrackets = Api\Bracket::getAll(); // Filter out active/completed brackets $brackets = []; foreach ($allBrackets as $bracket) { if ($active && ($bracket->state == BS_ELIMINATIONS || $bracket->state == BS_VOTING || $bracket->state == BS_NOMINATIONS)) { $bracket->title = Api\Round::getBracketTitleForActiveRound($bracket); $brackets[] = $bracket; } if (!$active && $bracket->state == BS_FINAL) { $brackets[] = $bracket; } } // Check for card images foreach ($brackets as $bracket) { if (is_readable('./images/bracket_' . $bracket->id . '_card.jpg')) { $bracket->cardImage = '/images/bracket_' . $bracket->id . '_card.jpg'; } else { $bracket->entrants = Api\Character::getRandomCharacters($bracket, 9); } } return $brackets; }, 'Controller::Brackets_displayBrackets_' . ($active ? 'active' : 'completed')); Lib\Display::addKey('page', 'brackets'); $title = $active ? 'Current Brackets' : 'Past Brackets'; Lib\Display::renderAndAddKey('content', 'bracketsView', ['brackets' => $brackets, 'title' => $title]); }
public static function emptyOrder($cacheId) { \Helper\ShoppingCart::emptyCartCache(); $mem = \Lib\Cache::init(); $mem->delete($cacheId . 'order'); $mem->delete($cacheId . 'paypalEX'); }
public static function set($key, $value) { if (!self::$_sess instanceof stdClass) { self::$_sess = new stdClass(); } self::$_sess->{$key} = $value; Cache::Set(SESSION_NAME . '_' . self::$_id, self::$_sess, SESSION_EXPIRE); }
public function __construct() { $hitsRateData = array(); $hitsCache = 0; $showCache = 0; $params = R::getParams('params'); $url = !empty($params['url']) ? $params['url'] : ''; $adId = !empty($params['adId']) ? $params['adId'] : ''; $noHeader = !empty($params['noHeader']) ? $params['noHeader'] : ''; if ($noHeader == 1) { //表示直连广告通过ajax请求写入点击次数 if ('XMLHttpRequest' !== $_SERVER['HTTP_X_REQUESTED_WITH']) { // 回應 非法 AJAX 請求,例如JSON格式 header('HTTP/1.1 404 Not found'); require ROOT_PATH . 'errors/404.php'; exit; } $url = ''; } elseif (!$adId || !$url) { return false; } $url = base64_decode(urldecode($url)); //memcached初始化 $mem = \Lib\Cache::init(); $hitsCache = $mem->get(self::CACHE_AD_HITS_KEY . $adId); $showCache = $mem->get(self::CACHE_AD_SHOW_KEY . $adId); //缓存点击次数, if (!$hitsCache) { $hitsCache += 1; $mem->set(self::CACHE_AD_HITS_KEY . $adId, $hitsCache); } else { $hitsCache += 1; if ($hitsCache < self::MAX_SIZE) { $mem->set(self::CACHE_AD_HITS_KEY . $adId, $hitsCache); } else { $hitsRateData[] = array('advertId' => $content['adId'], 'hits' => $hitsCache, 'showTimes' => $showCache); //重置计算次数 $showCache = 0; $hitsCache = 0; $mem->set(self::CACHE_AD_SHOW_KEY . $adId, $showCache); $mem->set(self::CACHE_AD_HITS_KEY . $adId, $hitsCache); //更新进数据库 $adM = new \Model\Ad(); $adM->updateHitsRate(array('advertUpdateStr' => json_encode($hitsRateData))); } } if (empty($noHeader)) { //header ( "Location:" . $url ); echo "<script>window.location.href='{$url}'</script>"; exit; } else { exit('success'); } return; }
/** * Returns an array of parent items for this object */ public function getParents() { $cacheKey = 'MalItem::getItemParents_' . $this->id; $retVal = Lib\Cache::Get($cacheKey); if (false === $retVal && $this->id) { $retVal = null; $result = Lib\Db::Query('SELECT i.* FROM mal_xref x INNER JOIN mal_items i ON i.item_id = x.mal_parent WHERE x.mal_child = :id ORDER BY x.mal_parent ASC', [':id' => $this->id]); if ($result && $result->count) { $retVal = []; while ($row = Lib\Db::Fetch($result)) { $retVal[] = new MalItem($row); } } Lib\Cache::Set($retVal, 3600); } return $retVal; }
private function __construct() { /** @var $config array */ include __DIR__ . '/../conf/config.php'; $dsn = 'mysql:host=localhost;dbname=' . $config['mysql']['database']; $username = $config['mysql']['user']; $password = $config['mysql']['password']; $options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION); $pdo = new \PDO($dsn, $username, $password, $options); if (DEBUG_BAR) { $this->pdo = new TraceablePDO($pdo); Bootstrap::getInstance()->debugbar->addCollector(new PDOCollector($this->pdo)); } else { $this->pdo = new \PDO($dsn, $username, $password, $options); } $this->cache = Cache::getInstance(); }
public static function generate(array $params) { $user = self::_checkLogin(); self::_enableAd(); $perma = array_shift($params); $bracket = Api\Bracket::getBracketByPerma($perma); if ($bracket->start <= time() && ($bracket->state == BS_ELIMINATIONS || $bracket->state == BS_VOTING || $bracket->state == BS_WILDCARD)) { $cacheKey = 'CurrentRound_' . $bracket->id . '_' . $user->id; $out = Lib\Cache::fetch(function () use($user, $bracket) { $out = new stdClass(); $out->userId = $user->id; $out->round = Api\Round::getCurrentRounds($bracket->id); $out->title = Api\Round::getBracketTitleForActiveRound($bracket); return $out; }, $cacheKey, CACHE_MEDIUM); if ($out) { $out->bracket = $bracket; $template = $out->bracket->state == BS_ELIMINATIONS ? 'eliminations' : 'voting'; if ($bracket->state != BS_ELIMINATIONS) { $entrantSwap = Lib\TestBucket::get('entrantSwap'); if ($entrantSwap !== 'control') { foreach ($out->round as $round) { // Interesting side effect that I had not considered before: // When TestBucket initializes, it's setting the random seed for the entire RNG (duh). // That means the following random line will produce a static set of results, so the // user experience won't be wonky. if ($entrantSwap === 'flip' || $entrantSwap === 'random' && rand() % 2 === 0) { $round = self::_flipEntrants($round); } } } } Lib\Display::addKey('page', 'vote'); Lib\Display::addKey('title', $bracket->name . ' - Voting' . DEFAULT_TITLE_SUFFIX); Lib\Display::renderAndAddKey('content', $template, $out); } } }
public static function generate(array $params) { $message = null; $bracket = self::_getBracket(array_shift($params)); if ($bracket) { $cacheKey = 'Controller::Admin::Advance_bracketAdvanceTime_' . $bracket->id; $lastBracketAdvance = Lib\Cache::Get($cacheKey); if (!$lastBracketAdvance || $lastBracketAdvance + self::BRACKET_ADVANCE_DELAY < time()) { Lib\Cache::Set($cacheKey, time()); $bracket->advance(); $message = new stdClass(); $message->type = 'success'; $message->message = $bracket->name . ' has advanced to the next round'; self::_refreshCaches($bracket); } else { $message = new stdClass(); $message->type = 'error'; $delta = $lastBracketAdvance + self::BRACKET_ADVANCE_DELAY - time(); $time = Lib\Util::relativeTime(time() - $delta); $message->message = $bracket->name . ' was recently advanced. Please wait ' . $time . ' before advancing again.'; } } return self::_main($message, true); }
<?php spl_autoload_register(function ($className) { require_once dirname(__FILE__) . '/../../' . str_replace('\\', '/', $className) . '.php'; }); \lib\Cache::permanent(); $marker = new \lib\Marker(filter_input_array(INPUT_GET)); $marker->show();
/** * Gets a record from the database by the primary key */ private function _getById($id) { $retVal = null; if (self::_verifyProperties($this)) { if (is_numeric($id)) { $cacheKey = 'Lib:Dal:' . $this->_dbTable . '_getById_' . $id; $retVal = Cache::Get($cacheKey); if (!$retVal) { $query = 'SELECT `' . implode('`, `', $this->_dbMap) . '` FROM `' . $this->_dbTable . '` '; $query .= 'WHERE `' . $this->_dbMap[$this->_dbPrimaryKey] . '` = :id LIMIT 1'; $result = Db::Query($query, [':id' => $id]); if (null !== $result && $result->count === 1) { $retVal = Db::Fetch($result); Cache::Set($cacheKey, $retVal); } } if ($retVal) { $this->copyFromDbRow($retVal); } } else { throw new Exception('ID must be a number'); } } else { throw new Exception('Class must have "_dbTable", "_dbMap", and "_dbPrimaryKey" properties to use method "getById"'); } }
/** * Refreshes various generic caches. This is expensive; use sparingly */ protected static function _refreshCaches(Api\Bracket $bracket = null) { Lib\Cache::setDisabled(true); // Refresh the main collections Api\Bracket::getAll(); Api\Bracket::getUserOwnedBrackets(self::$_user); \Controller\Brackets::generate(['past']); \Controller\Brackets::generate([]); // Refresh a single bracket if specified if ($bracket) { Api\Bracket::getBracketByPerma($bracket->perma); Api\Round::getCurrentRounds($bracket->id); $bracket->getResults(); } Lib\Cache::setDisabled(false); }
/** * Makes an internal API call */ private static function _internal($module, $method, $params, $cache) { global $_apiHits; $cacheKey = md5($module . '-' . $method . '-' . serialize($params)); $retVal = Lib\Cache::Get($cacheKey); if ($retVal === false || $cache == 0) { $_apiHits++; $retVal = Api\DxApi::handleRequest($module, $method, $params); Lib\Cache::Set($cacheKey, $retVal); } return $retVal; }
/** * Makes an API call to another instance of DxApi via REST */ private static function _external($module, $method, $params, $cache, $apiUri) { global $_apiHits; $qs = '/index.php?type=json&method=' . $module . '.' . $method; // Build the query string if (count($params) > 0) { foreach ($params as $key => $val) { $qs .= "&{$key}=" . urlencode($val); } } // Check to see if there is a cached version of this $cacheKey = md5($apiUri . $qs); $retVal = Cache::Get($cacheKey); if ($retVal === false || $cache == 0) { $_apiHits++; $file = file_get_contents($apiUri . $qs); $retVal = json_decode($file); // Only cache on success if ($retVal->status->ret_code == 0) { Cache::Set($cacheKey, $retVal, $cache); } } // Return the request return $retVal; }
private function getGpx() { if ($this->wk) { \lib\Error::send(404, 'Week view for GPX is not (yet) implemented'); } else { $this->doCalc(); if ($this->global) { if (is_null($this->output['global'])) { \lib\Error::send(404, 'Data not yet available'); } $this->lat = $this->output['global']->lat; $this->lng = $this->output['global']->lng; $filename = 'global'; } else { $hashData = $this->lng > -30 ? $this->output['east'] : $this->output['west']; if (is_null($hashData)) { \lib\Error::send(404, 'Data not yet available'); } $filename = $this->lat . '_' . $this->lng; $this->lat .= substr($hashData->lat, 1); $this->lng .= substr($hashData->lng, 1); } \lib\Cache::permanent(); header('Content-type: text/xml'); header('Content-type: application/force-download;charset=utf-8'); header('Content-Disposition: attachment; filename="geohash_' . $this->date->format('Y-m-d') . '_' . $filename . '.gpx"'); echo '<?xml version="1.0"?> <gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="geohashing.info"> <metadata> <name>Geohash ' . $this->date->format('Y-m-d') . '</name> </metadata> <wpt lat="' . $this->lat . '" lon="' . $this->lng . '"> <name>GH ' . $this->date->format('Y-m-d') . ' ' . $this->graticule . '</name> </wpt> </gpx>'; } }
/** * Advances a standard bracket tier */ private function _advanceBracket() { $rounds = Round::getCurrentRounds($this->id, true); if (count($rounds) > 1) { for ($i = 0, $count = count($rounds); $i < $count; $i += 2) { // Get the round winners $winner1 = $rounds[$i]->getWinnerId(); $winner2 = $rounds[$i + 1]->getWinnerId(); // Create the round for the next tier $newRound = new Round(); $newRound->bracketId = $this->id; $newRound->tier = $rounds[$i]->tier + 1; $newRound->group = $rounds[$i]->group; $newRound->order = $i / 2; $newRound->character1Id = $winner1; $newRound->character2Id = $winner2; $newRound->sync(); // Finalize the current tier $rounds[$i]->getVoteCount(); $rounds[$i]->final = true; $rounds[$i]->sync(); $rounds[$i + 1]->getVoteCount(); $rounds[$i + 1]->final = true; $rounds[$i + 1]->sync(); } } else { if (count($rounds) === 1) { $round = $rounds[0]; $round->getVoteCount(); $round->final = true; $round->sync(); $this->winner = $round->getWinner(); $this->winnerCharacterId = $this->winner->id; $this->state = BS_FINAL; $this->sync(); } } // Clear the results cache Lib\Cache::Set('Api:Bracket:getResults_' . $this->id, false, 1); }
/** * Returns random completed rounds */ public static function getRandomCompletedRounds($count) { $count = is_numeric($count) ? $count : 10; return Lib\Cache::fetch(function () use($count) { $retVal = null; $query = 'SELECT * FROM `round` WHERE round_final = 1 AND round_tier > 0 AND round_character2_id > 1 ORDER BY RAND() LIMIT ' . $count; return self::_getRoundsAndCharacters($query); }, 'Round::getRandomCompletedRounds_' . $count, CACHE_LONG * 24); }
private static function _vote($user) { $out = new stdClass(); $out->success = false; $bracketId = Lib\Url::Post('bracketId', true); $bracket = Api\Bracket::getById($bracketId); if ($bracket) { $state = $bracket ? (int) $bracket->state : null; if ($bracket->isLocked()) { $out->message = 'Voting is closed for this round. Please refresh to see the latest round.'; } else { if ($state === BS_ELIMINATIONS || $state === BS_VOTING) { if (self::_verifyAccountAge($user, $bracket)) { // Break the votes down into an array of round/character objects $votes = []; foreach ($_POST as $key => $val) { if (strpos($key, 'round:') === 0) { $key = str_replace('round:', '', $key); $obj = new stdClass(); $obj->roundId = (int) $key; $obj->characterId = (int) $val; $votes[] = $obj; } } $count = count($votes); if ($count > 0) { $query = 'INSERT INTO `votes` (`user_id`, `vote_date`, `round_id`, `character_id`, `bracket_id`) VALUES '; $params = [':userId' => $user->id, ':date' => time(), ':bracketId' => $bracketId]; $insertCount = 0; // Only run an insert for rounds that haven't been voted on $rounds = Api\Votes::getOpenRounds($user, $votes); for ($i = 0; $i < $count; $i++) { if (!isset($rounds[$votes[$i]->roundId])) { $query .= '(:userId, :date, :round' . $i . ', :character' . $i . ', :bracketId),'; $params[':round' . $i] = $votes[$i]->roundId; $params[':character' . $i] = $votes[$i]->characterId; $insertCount++; $rounds[$votes[$i]->roundId] = true; } } if ($insertCount > 0) { $query = substr($query, 0, strlen($query) - 1); if (Lib\Db::Query($query, $params)) { $out->success = true; // I am vehemently against putting markup in the controller, but there's much refactor needed to make this right // So, that's a note that it will be changed in the future $out->message = 'Your votes were successfully submitted! <a href="/results/' . $bracket->perma . '">View Results</a>'; // Oops, I did it again... if ($bracket->externalId) { $out->message .= ' or <a href="http://redd.it/' . $bracket->externalId . '" target="_blank">discuss on reddit</a>.'; } // Clear any user related caches $round = Api\Round::getById($votes[0]->roundId); Lib\Cache::Set('GetBracketRounds_' . $bracketId . '_' . $round->tier . '_' . $round->group . '_' . $user->id, false); Lib\Cache::Set('GetBracketRounds_' . $bracketId . '_' . $round->tier . '_all_' . $user->id, false); Lib\Cache::Set('CurrentRound_' . $bracketId . '_' . $user->id, false); $bracket->getVotesForUser($user, true); } else { $out->message = 'There was an unexpected error. Please try again in a few moments.'; } } else { $out->message = 'Voting for this round has closed'; $out->code = 'closed'; } } else { $out->message = 'No votes were submitted'; } } else { $out->message = 'Your reddit account is not old enough to vote in this bracket'; } } else { $out->message = 'Voting is closed on this bracket'; $out->code = 'closed'; } } } else { $out->message = 'Invalid parameters'; } return $out; }
/** * 调用webservice.例:<br /> * [code] * $interface = $this->getInterface('json');//在model中实例化数据接口 * $data = $interface->call(null,array('id'=>23,'status'=0));//使用\config\Webserice::serviceUrl 作为webservice的URL * $data2 = $interface->call('product/product/getDetails',array('pid'=>3123)); //使用\config\Webserice::serviceUrl并附加根据模块名和动作名组成的子空间地址 * [/code] * 当直接使用\config\Webserice::serviceUrl定义的地址或setUrl()指定的地址时需留$subNamespace为null * @param string $subNamespace 根据命名空间,模块及方法区分的子地址,属于webservice url中的一段 * @param array $paramGet 附加到url中进行提交的数据 * @param array $paramPost 通过post进行提交的数据 * @param boolen $forceArray 强制返回关联数组.默认true * @param string $appendix api地址后缀名称.默认为.htm * @return Object json deocde后的对象 */ public function call($subNamespace, $paramGet = array(), $paramPost = array(), $forceArray = true, $appendix = '.htm') { if (DEBUG_MODE) { $invokeStartTime = sprintf('%.8f', microtime(true)); $invokeKey = 'CallStartTime:' . $invokeStartTime; $e = new \Exception(); self::$wsCallInfoStack[$invokeKey]['StackTrace'] = $e->getTraceAsString(); } $serviceUrl = $this->serviceUrl; /** * 作为页面内及memcache缓存key * @var string */ $cacheKey = md5($serviceUrl . $subNamespace . serialize($paramPost) . serialize($paramGet)); if (isset(self::$cachedResult[$cacheKey])) { return self::$cachedResult[$cacheKey]; } $result = false; //20120905需求,当http://www.milanoo.com/?nocache=true,则不需要缓存 if (isset($_GET['nocache']) && $_GET['nocache'] == 'true') { $this->needCache = false; } if ($this->needCache) { ini_set('memcache.chunk_size', 1042 * 90); $m = \Lib\Cache::init(); $result = $m->get($cacheKey); if (DEBUG_MODE) { self::$wsCallInfoStack[$invokeKey]['TimeConsumedInFetchFromMemcache'] = sprintf('%.8f', (microtime(true) - $invokeStartTime) * 1000) . 'ms'; } } //当读取缓存失败或者不需要缓存时 if (false === $result || !$this->needCache) { if ($this->needCache) { $dataBak = $m->get($cacheKey . $this->suffix); if (false !== $dataBak) { //主键缓存失败时,从副键缓存中读取至主键,以便其后的请求读取成功 $m->set($cacheKey, $dataBak, 0, $this->cacheTime); if (DEBUG_MODE) { //标记读取了副键缓存的数据 self::$wsCallInfoStack[$invokeKey]['CacheHit'] = 2; } } if (DEBUG_MODE) { self::$wsCallInfoStack[$invokeKey]['TimeConsumedInFetchFromMemcache'] = sprintf('%.8f', (microtime(true) - $invokeStartTime) * 1000) . 'ms'; if (false !== $dataBak) { self::$wsCallInfoStack[$invokeKey]['ContentLengthStoredInMemcache'] = number_format(strlen($dataBak)); } } } if (is_string($subNamespace)) { //@todo webservice url地址需根据webservice的地址规则进行改变 $serviceUrl = rtrim($serviceUrl, '?\\/') . '/' . $subNamespace . $appendix; } $appendedValues = array(); if (is_array($paramGet)) { foreach ($paramGet as $k => $v) { $appendedValues[] = $k . '=' . urlencode($v); } } $appendedValues = implode('&', $appendedValues); if (!empty($appendedValues)) { if (strpos($this->serviceUrl, '?') === false) { $appendedValues = '?' . $appendedValues; } else { $appendedValues = '&' . $appendedValues; } $serviceUrl .= $appendedValues; } //die($serviceUrl); $ch = curl_init(); if ($this->requestMethod == 'POST') { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $paramPost); } curl_setopt_array($ch, array(CURLOPT_URL => $serviceUrl, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => \config\Webservice::TIMEOUT, CURLOPT_HEADER => true)); if (DEBUG_MODE) { self::$wsCallInfoStack[$invokeKey]['TimeStart'] = $invokeStartTime; self::$wsCallInfoStack[$invokeKey]['URL'] = $serviceUrl; self::$wsCallInfoStack[$invokeKey]['GET'] = $paramGet; self::$wsCallInfoStack[$invokeKey]['POST'] = $paramPost; } $rawReturn = curl_exec($ch); if (DEBUG_MODE) { $this->communicationInfo = curl_getinfo($ch); self::$wsCallInfoStack[$invokeKey]['Info'] = $this->communicationInfo; self::$wsCallInfoStack[$invokeKey]['TimeConsumedInWebservice'] = sprintf('%.8f', (microtime(true) - $invokeStartTime) * 1000) . 'ms'; } if ($errNo = curl_errno($ch)) { $err = new \Exception('webservice错误:' . "\n" . var_export($this->communicationInfo, true) . "\n"); error_log($err->getMessage() . "\n" . $err->getTraceAsString()); $this->errorInfo[$errNo] = curl_error($ch); if (DEBUG_MODE) { self::$wsCallInfoStack[$invokeKey]['Error'] = $this->errorInfo; debug::setInfo('WSCall', self::$wsCallInfoStack); } curl_close($ch); if ($this->needCache && false !== $dataBak) { //webservice 调用失败,返回副键值 $dataBak = gzuncompress($dataBak); if (DEBUG_LEVEL === 0) { self::$wsCallInfoStack[$invokeKey]['CachedData'] = $dataBak; } return self::$cachedResult[$cacheKey] = json_decode($dataBak, $forceArray); } else { return false; } } curl_close($ch); $parsedRawReturn = explode("\r\n\r\n", $rawReturn); if (count($parsedRawReturn) > 1) { $rawReturn = array_pop($parsedRawReturn); } else { $rawReturn = ''; } $rawReturnHeaders = explode("\r\n", array_pop($parsedRawReturn)); $headers = array('Protocol' => array_shift($rawReturnHeaders)); foreach ($rawReturnHeaders as $header) { $header = explode(': ', $header); $headers[$header[0]] = $header[1]; } if (isset($headers['Content-Encoding'])) { $return = gzuncompress($rawReturn); } else { $return = $rawReturn; $rawReturn = gzcompress($rawReturn, 9); } if (DEBUG_MODE) { $this->rawResponse = $return; } $return = json_decode($return, $forceArray); if (DEBUG_MODE) { if (DEBUG_LEVEL === 0) { self::$wsCallInfoStack[$invokeKey]['RawResponse'] = $this->rawResponse; } debug::setInfo('WSCall', self::$wsCallInfoStack); } if (($decodeError = json_last_error()) !== JSON_ERROR_NONE && !$this->needCache) { //webservice返回的数据解码错误 $err = new \Exception('数据解析错误.' . "\n" . 'webservice 返回:' . $this->rawResponse . "\n"); error_log($err->getMessage() . "\n" . $err->getTraceAsString()); return false; } else { if ($this->needCache) { if ($decodeError !== JSON_ERROR_NONE || !isset($return['code']) || $return['code'] >= 10000) { //解码失败,或者没有返回状态code属性, 或者webservice APP报错系统错误 if ($dataBak !== false) { //结果错误时则使用上次的正确结果(非开发模式下) $return = gzuncompress($dataBak); $return = json_decode($return, $forceArray); $rawReturn =& $dataBak; } } else { //当只有结果正确时才更新永久缓存,尽可能减小cache操作 $m->set($cacheKey . $this->suffix, $rawReturn, 0, 0); } $m->set($cacheKey, $rawReturn, 0, $this->cacheTime); } self::$cachedResult[$cacheKey] = $return; } if (DEBUG_MODE) { debug::setInfo('WSCall', self::$wsCallInfoStack); } return $return; } else { if (DEBUG_MODE) { self::$wsCallInfoStack[$invokeKey]['ContentLengthStoredInMemcache'] = number_format(strlen($result)); } $result = gzuncompress($result); if (DEBUG_MODE) { //标记读取了副键缓存的数据 self::$wsCallInfoStack[$invokeKey]['CacheHit'] = 1; if (DEBUG_LEVEL === 0) { self::$wsCallInfoStack[$invokeKey]['CachedData'] = $result; } debug::setInfo('WSCall', self::$wsCallInfoStack); } return self::$cachedResult[$cacheKey] = json_decode($result, $forceArray); } }
/** * Retrieves a stashed message from caches and then clears it */ protected static function _getStashedMessage() { $retVal = null; if (self::$_user) { $cacheKey = self::_stashCacheKey(); $retVal = Lib\Cache::Get($cacheKey); Lib\Cache::Set($cacheKey, false); } return $retVal; }
<?php namespace Lib; use Memcache; use Predis; define('CACHE_LONG', 3600); define('CACHE_MEDIUM', 600); define('CACHE_SHORT', 60); if (!defined('DISABLE_CACHE')) { define('DISABLE_CACHE', false); } if (!DISABLE_CACHE) { Cache::Connect(); } // memcache class class Cache { private static $_memcache; private static $_redis; private static $_disabled = false; public static function Connect($host = 'localhost', $port = 11211) { self::$_memcache = new Memcache(); if (!self::$_memcache->pconnect($host, $port)) { self::$_memcache = null; } self::setDisabled(isset($_GET['flushCache'])); } public static function Set($key, $val, $expiration = 600) {
/** * Returns a random number of characters from bracket */ public static function getRandomCharacters(Bracket $bracket, $count) { if (is_numeric($count)) { return Lib\Cache::fetch(function () use($bracket, $count) { $retVal = []; $result = Lib\Db::Query('SELECT * FROM `character` WHERE bracket_id = :id ORDER BY RAND() LIMIT ' . $count, [':id' => $bracket->id]); if ($result && $result->count) { while ($row = Lib\Db::Fetch($result)) { $retVal[] = new Character($row); } } return $retVal; }, 'Api::Character_getRandomCharacters_' . $bracket->id . '_' . $count); } return []; }
/** * Does fuzzy searching for characters within a bracket */ public static function searchBracketNominees($query, $bracketId) { return Lib\Cache::fetch(function () use($query, $bracketId) { $retVal = []; $params = [':bracketId' => $bracketId, ':queryA' => $query . '%', ':queryB' => '% ' . $query . '%']; $result = Lib\Db::Query('SELECT * FROM `nominee` WHERE bracket_id = :bracketId AND (nominee_name LIKE :queryA OR nominee_name LIKE :queryB)', $params); if ($result && $result->count) { while ($row = Lib\Db::Fetch($result)) { $retVal[] = new Nominee($row); } } return $retVal; }, 'Api::Nominee_searchBracketNominees_' . $query . '_' . $bracketId, CACHE_MEDIUM); }
private static function _displayCharacters(Api\Bracket $bracket) { $out = new stdClass(); Lib\Cache::setDisabled(true); $out->characters = Api\Character::getByBracketId($bracket->id); $out->bracket = $bracket; Lib\Display::renderAndAddKey('content', 'admin/characters', $out); Lib\Cache::setDisabled(false); }
/** * Generates a list of characters in a bracket (ordered by seed) and their performance * in said bracket */ public static function getEntrantPerformanceStats(Bracket $bracket, $force = false) { return Lib\Cache::fetchLongCache(function () use($bracket) { // Get all tourney rounds and characters for this bracket $characters = Character::queryReturnAll(['bracketId' => $bracket->id, 'seed' => ['null' => false]], ['seed' => 'asc']); $rounds = Round::queryReturnAll(['bracketId' => $bracket->id, 'final' => 1, 'tier' => ['gt' => 0]], ['id' => 'asc']); // Create a hash out of the characters $temp = []; foreach ($characters as $character) { $temp[$character->id] = $character; } $characters = $temp; // Sort the rounds out based on character for faster access later $characterRounds = []; foreach ($rounds as $round) { // Decorate the round with full character models $round->character1 = $characters[$round->character1Id]; $round->character2 = $characters[$round->character2Id]; self::_addRoundToCharacterRounds($round, $round->character1Id, $characterRounds); self::_addRoundToCharacterRounds($round, $round->character2Id, $characterRounds); } $retVal = []; foreach ($characters as $character) { $roundsForCharacter = array_values($characterRounds[$character->id]); $closestDiff = -1; $closestRound = null; $lostTo = null; $totalVotes = 0; foreach ($roundsForCharacter as $round) { // Heheheh... so gross $isCharacter1 = $round->character1Id == $character->id; $totalVotes += $isCharacter1 ? $round->character1Votes : $round->character2Votes; $diff = abs($round->character1Votes - $round->character2Votes); if ($diff < $closestDiff || $closestDiff === -1) { $closestDiff = $diff; // This case should be small enough that re-instantiating through a loop // shouldn't prove too much of a performance concern (especially since // it's generated only once per new round). Will monitor in production $closestRound = (object) ['character' => $isCharacter1 ? $round->character2 : $round->character1, 'difference' => $closestDiff, 'round' => $round]; } $lost = $isCharacter1 && $round->character1Votes < $round->character2Votes || !$isCharacter1 && $round->character2Votes < $round->character1Votes; $lostTo = $lost ? (object) ['character' => $isCharacter1 ? $round->character2 : $round->character1, 'lostBy' => $diff, 'round' => $round] : null; } $retVal[] = (object) ['character' => $character, 'closestRound' => $closestRound, 'lostTo' => $lostTo, 'totalVotes' => $totalVotes, 'group' => chr(65 + $roundsForCharacter[0]->group)]; } return $retVal; }, 'Stats::PerformanceStats_' . $bracket->id, $force); }