messagecache.php
来自「php 开发的内容管理系统」· PHP 代码 · 共 582 行 · 第 1/2 页
PHP
582 行
<?php/** * * @package MediaWiki * @subpackage Cache *//** * */define( 'MSG_LOAD_TIMEOUT', 60);define( 'MSG_LOCK_TIMEOUT', 10);define( 'MSG_WAIT_TIMEOUT', 10);/** * Message cache * Performs various useful MediaWiki namespace-related functions * * @package MediaWiki */class MessageCache { var $mCache, $mUseCache, $mDisable, $mExpiry; var $mMemcKey, $mKeys, $mParserOptions, $mParser; var $mExtensionMessages = array(); var $mInitialised = false; var $mDeferred = true; function __construct( &$memCached, $useDB, $expiry, $memcPrefix) { wfProfileIn( __METHOD__ ); $this->mUseCache = !is_null( $memCached ); $this->mMemc = &$memCached; $this->mDisable = !$useDB; $this->mExpiry = $expiry; $this->mDisableTransform = false; $this->mMemcKey = $memcPrefix.':messages'; $this->mKeys = false; # initialised on demand $this->mInitialised = true; wfProfileIn( __METHOD__.'-parseropt' ); $this->mParserOptions = new ParserOptions( $u=NULL ); wfProfileOut( __METHOD__.'-parseropt' ); $this->mParser = null; # When we first get asked for a message, # then we'll fill up the cache. If we # can return a cache hit, this saves # some extra milliseconds $this->mDeferred = true; wfProfileOut( __METHOD__ ); } /** * Try to load the cache from a local file */ function loadFromLocal( $hash ) { global $wgLocalMessageCache, $wgDBname; $this->mCache = false; if ( $wgLocalMessageCache === false ) { return; } $filename = "$wgLocalMessageCache/messages-$wgDBname"; wfSuppressWarnings(); $file = fopen( $filename, 'r' ); wfRestoreWarnings(); if ( !$file ) { return; } // Check to see if the file has the hash specified $localHash = fread( $file, 32 ); if ( $hash == $localHash ) { // All good, get the rest of it $serialized = fread( $file, 1000000 ); $this->mCache = unserialize( $serialized ); } fclose( $file ); } /** * Save the cache to a local file */ function saveToLocal( $serialized, $hash ) { global $wgLocalMessageCache, $wgDBname; if ( $wgLocalMessageCache === false ) { return; } $filename = "$wgLocalMessageCache/messages-$wgDBname"; $oldUmask = umask( 0 ); wfMkdirParents( $wgLocalMessageCache, 0777 ); umask( $oldUmask ); $file = fopen( $filename, 'w' ); if ( !$file ) { wfDebug( "Unable to open local cache file for writing\n" ); return; } fwrite( $file, $hash . $serialized ); fclose( $file ); @chmod( $filename, 0666 ); } function loadFromScript( $hash ) { global $wgLocalMessageCache, $wgDBname; if ( $wgLocalMessageCache === false ) { return; } $filename = "$wgLocalMessageCache/messages-$wgDBname"; wfSuppressWarnings(); $file = fopen( $filename, 'r' ); wfRestoreWarnings(); if ( !$file ) { return; } $localHash=substr(fread($file,40),8); fclose($file); if ($hash!=$localHash) { return; } require("$wgLocalMessageCache/messages-$wgDBname"); } function saveToScript($array, $hash) { global $wgLocalMessageCache, $wgDBname; if ( $wgLocalMessageCache === false ) { return; } $filename = "$wgLocalMessageCache/messages-$wgDBname"; $oldUmask = umask( 0 ); wfMkdirParents( $wgLocalMessageCache, 0777 ); umask( $oldUmask ); $file = fopen( $filename.'.tmp', 'w'); fwrite($file,"<?php\n//$hash\n\n \$this->mCache = array("); foreach ($array as $key => $message) { fwrite($file, "'". $this->escapeForScript($key). "' => '" . $this->escapeForScript($message). "',\n"); } fwrite($file,");\n?>"); fclose($file); rename($filename.'.tmp',$filename); } function escapeForScript($string) { $string = str_replace( '\\', '\\\\', $string ); $string = str_replace( '\'', '\\\'', $string ); return $string; } /** * Loads messages either from memcached or the database, if not disabled * On error, quietly switches to a fallback mode * Returns false for a reportable error, true otherwise */ function load() { global $wgLocalMessageCache, $wgLocalMessageCacheSerialized; if ( $this->mDisable ) { static $shownDisabled = false; if ( !$shownDisabled ) { wfDebug( "MessageCache::load(): disabled\n" ); $shownDisabled = true; } return true; } $fname = 'MessageCache::load'; wfProfileIn( $fname ); $success = true; if ( $this->mUseCache ) { $this->mCache = false; # Try local cache wfProfileIn( $fname.'-fromlocal' ); $hash = $this->mMemc->get( "{$this->mMemcKey}-hash" ); if ( $hash ) { if ($wgLocalMessageCacheSerialized) { $this->loadFromLocal( $hash ); } else { $this->loadFromScript( $hash ); } } wfProfileOut( $fname.'-fromlocal' ); # Try memcached if ( !$this->mCache ) { wfProfileIn( $fname.'-fromcache' ); $this->mCache = $this->mMemc->get( $this->mMemcKey ); # Save to local cache if ( $wgLocalMessageCache !== false ) { $serialized = serialize( $this->mCache ); if ( !$hash ) { $hash = md5( $serialized ); $this->mMemc->set( "{$this->mMemcKey}-hash", $hash, $this->mExpiry ); } if ($wgLocalMessageCacheSerialized) { $this->saveToLocal( $serialized,$hash ); } else { $this->saveToScript( $this->mCache, $hash ); } } wfProfileOut( $fname.'-fromcache' ); } # If there's nothing in memcached, load all the messages from the database if ( !$this->mCache ) { wfDebug( "MessageCache::load(): loading all messages\n" ); $this->lock(); # Other threads don't need to load the messages if another thread is doing it. $success = $this->mMemc->add( $this->mMemcKey.'-status', "loading", MSG_LOAD_TIMEOUT ); if ( $success ) { wfProfileIn( $fname.'-load' ); $this->loadFromDB(); wfProfileOut( $fname.'-load' ); # Save in memcached # Keep trying if it fails, this is kind of important wfProfileIn( $fname.'-save' ); for ($i=0; $i<20 && !$this->mMemc->set( $this->mMemcKey, $this->mCache, $this->mExpiry ); $i++ ) { usleep(mt_rand(500000,1500000)); } # Save to local cache if ( $wgLocalMessageCache !== false ) { $serialized = serialize( $this->mCache ); $hash = md5( $serialized ); $this->mMemc->set( "{$this->mMemcKey}-hash", $hash, $this->mExpiry ); if ($wgLocalMessageCacheSerialized) { $this->saveToLocal( $serialized,$hash ); } else { $this->saveToScript( $this->mCache, $hash ); } } wfProfileOut( $fname.'-save' ); if ( $i == 20 ) { $this->mMemc->set( $this->mMemcKey.'-status', 'error', 60*5 ); wfDebug( "MemCached set error in MessageCache: restart memcached server!\n" ); } } $this->unlock(); } if ( !is_array( $this->mCache ) ) { wfDebug( "MessageCache::load(): individual message mode\n" ); # If it is 'loading' or 'error', switch to individual message mode, otherwise disable # Causing too much DB load, disabling -- TS $this->mDisable = true; /* if ( $this->mCache == "loading" ) { $this->mUseCache = false; } elseif ( $this->mCache == "error" ) { $this->mUseCache = false; $success = false; } else { $this->mDisable = true; $success = false; }*/ $this->mCache = false; } } wfProfileOut( $fname ); $this->mDeferred = false; return $success; } /** * Loads all or main part of cacheable messages from the database */ function loadFromDB() { global $wgAllMessagesEn, $wgLang; $fname = 'MessageCache::loadFromDB'; $dbr =& wfGetDB( DB_SLAVE ); if ( !$dbr ) { throw new MWException( 'Invalid database object' );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?