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 + -
显示快捷键?