天天看点

mediawiki源码分析-入口Index.php简要分析

转自 donnki 个人空间 : http://www.phpchina.com/52027/viewspace_20042.html Wiki源码里注释挺完整的,基本上每一个文件和类的作用,每一个方法的参数、返回值都写清楚了,每一个常量、全局变量也都有详细的注释。另外代码片段的作用也有注释。 而且作者很有意思。看这段注释,哈哈: // This probably shouldn't even happen. ohh man, oh yuck. // But for interwiki transclusion it sometimes does. // Shit. Shit shit shit. 现在从入口index.php来分析MediaWiki源码。 index.php源文件全部内容如下: getVal( 'maxlag' ); if ( !is_null( $maxLag ) ) { if ( !$mediaWiki->checkMaxLag( $maxLag ) ) { exit; } } # Query string fields $action = $wgRequest->getVal( 'action', 'view' ); $title = $wgRequest->getVal( 'title' ); $wgTitle = $mediaWiki->checkInitialQueries( $title,$action,$wgOut, $wgRequest, $wgContLang ); if ($wgTitle == NULL) { unset( $wgTitle ); } # # Send Ajax requests to the Ajax dispatcher. # if ( $wgUseAjax && $action == 'ajax' ) { require_once( $IP . '/includes/AjaxDispatcher.php' ); $dispatcher = new AjaxDispatcher(); $dispatcher->performAction(); $mediaWiki->restInPeace( $wgLoadBalancer ); exit; } wfProfileOut( 'main-misc-setup' ); # Setting global variables in mediaWiki $mediaWiki->setVal( 'Server', $wgServer ); $mediaWiki->setVal( 'DisableInternalSearch', $wgDisableInternalSearch ); $mediaWiki->setVal( 'action', $action ); $mediaWiki->setVal( 'SquidMaxage', $wgSquidMaxage ); $mediaWiki->setVal( 'EnableDublinCoreRdf', $wgEnableDublinCoreRdf ); $mediaWiki->setVal( 'EnableCreativeCommonsRdf', $wgEnableCreativeCommonsRdf ); $mediaWiki->setVal( 'CommandLineMode', $wgCommandLineMode ); $mediaWiki->setVal( 'UseExternalEditor', $wgUseExternalEditor ); $mediaWiki->setVal( 'DisabledActions', $wgDisabledActions ); $wgArticle = $mediaWiki->initialize ( $wgTitle, $wgOut, $wgUser, $wgRequest ); $mediaWiki->finalCleanup ( $wgDeferredUpdateList, $wgLoadBalancer, $wgOut ); # Not sure when $wgPostCommitUpdateList gets set, so I keep this separate from finalCleanup $mediaWiki->doUpdates( $wgPostCommitUpdateList ); $mediaWiki->restInPeace( $wgLoadBalancer ); ?> 第一句:require_once( './includes/WebStart.php' ); Webstart.php文件执行的操作是为一个Web请求进行初始化设置:进行安全检查、调试开启(注1)、装载配置文件里的全局变量及常量。最后调用setup.php执行后继操作(注2)。 这个文件中调用了Defines.php(常量)、LocalSettings.php(配置文件,全局变量。),另外还在这里根据配置开启字符缓冲区,回调方法是OutputHandler.php的wfOutputHandler方法。 setup.php里require_once了一大堆文件:AutoLoader.php、Exception.php、GlobalFunctions.php、Hooks.php、Namespace.php、ProxyTools.php、ObjectCache.php、ImageFunctions.php、StubObject.php……另外还初始化了一些重要的全局变量如$wgLoadBalancer、$wgUser、$wgRequest等。 接下来: require_once( "includes/Wiki.php" ); $mediaWiki = new MediaWiki(); wiki.php里定义了MediaWiki类。其中包括很多的wiki对象的方法。接着为$mediaWiki对象开辟内存空间。MediaWiki类的构造函数只有一句:$this->GET = $_GET;(类成员变量$GET存放$_GET的信息。应该是为了让面向对象来得很彻底吧,呵呵) 接下来,经过一步验证$maxLag(暂时不知道是做何用的)后,从已经在setup.php中初始化的$wgRequest对象中取中事件类型$action和主题$title。在这里我将$wgRequest对象对应的WebRequest类理解成封装$_REQUEST数组的类。然后以$action、$title及其它上下文作为参数通过$mediaWiki->checkInitialQueries取得一个Title对象。 AJAX判断。如果开启AJAX功能,且$action值为ajax,则将Ajax请求发送到Ajax dispather处理器。这里由于我没开启ajax功能,所以暂时没从这里跟踪进去。 接下来,为$mediaWiki的成员变量数组$param设置了很多的值(暂时未具体了解其意图)。 $wgArticle = $mediaWiki->initialize ( $wgTitle, $wgOut, $wgUser, $wgRequest ); 这一句应该比较关键。源码注释上写的是初始化一切! Initialization of ... everything,注意initialize()方法中调用了这么一段: $article = $this->initializeArticle( $title, $request ); if( is_object( $article ) ) { $this->performAction( $output, $article, $title, $user, $request ); }elseif( is_string( $article ) ) { $output->redirect( $article ); } else { throw new MWException( "Shouldn't happen: MediaWiki::initializeArticle() returned neither an object nor a URL" ); } 这里的performAction()应该是处理不同的action请求。默认的$action为"view",因此暂未跟踪入这个方法体里。 最后返回一个Article对象,或者为NULL。 $mediaWiki->finalCleanup ( $wgDeferredUpdateList, $wgLoadBalancer, $wgOut ); 处理延期的更新、写入数据库及为页面输出。 由于不确定$wgPostCommitUpdateList是否已经取得了结果集,因此单独执行$mediaWiki->doUpdates( $wgPostCommitUpdateList )进行最后的清理工作。 最后调用restInPeace()友好的关闭数据库连接。 注1:这里我不确定。原文是“start the profiler”,为其定义了wfProfileIn和wfProfileOut两个方法。从上下文来看应该是做调试用的。我没开启调试功能,所以在$haveProctitle=function_exists("setproctitle");(来源于ProfileStub.php)我全文搜索"function setproctitle"没搜到,因此$haveProctitle值为false,在后文的判断中没执行任何操作。也即没开启调试吧。 注2:是否调用setup.php取决于常量“MW_NO_SETUP”是否被定义: if ( !defined( 'MW_NO_SETUP' ) ) { require_once( './includes/Setup.php' ); }更为详细的分析具体的方法体,有待进一步研究。

继续阅读