您好,欢迎访问一九零五行业门户网

mediawiki1.24源码分析(一)

所有分析说明采用文字使用浅红色、小四号楷体。
index.php
//mediawiki程序入口
this is the main web entry point for mediawiki.
现在开始看程序的第一句代码,判断php版本是否是5.3.2及以上,如果不是就在页面报错提示。
php代码 
if ( !function_exists( 'version_compare' ) || version_compare( php_version, '5.3.2' ) // we need to use dirname( __file__ ) here cause __dir__ is php5.3+require dirname( __file__ ) . '/includes/phpversionerror.php';  wfphpversionerror( 'index.php' );  }  接下来是比较关键的代码了,引入一个php文件 webstart.php。
php代码 
require __dir__ . '/includes/webstart.php';  webstart.php
 * this does the initial set up for a web request.
 * it does some security checks, starts the profiler and loads the
 * configuration, and optionally loads setup.php depending on whether
 * mw_no_setup is defined.
 * setup.php (if loaded) then sets up globalfunctions, the autoloader,
 * and the configuration globals (though not $wgtitle).
webstart.php的文件注解部分如上,大概说此文件执行的操作是为一个web请求进行初始化设置:进行安全检查、调试开启、装载配置文件里的全局变量及常量。最后如果没有安装过mediawiki则调用setup.php执行安装mediawiki操作。这个文件中调用了defines.php(常量)、localsettings.php(配置文件,全局变量),另外还在这里根据配置开启字符缓冲区,回调方法是outputhandler.php的wfoutputhandler方法。
php代码 
if ( ini_get( 'register_globals' ) ) {  die( 'mediawiki does not support installations where register_globals is enabled. '. 'please see mediawiki.org '. 'for help on how to disable it.' );  }  如果php配置项register_globals是打开状态(on),则mediawiki无法运行。
# bug 15461: make ie8 turn off content sniffing. everybody else should ignore this
# we're adding it here so that it's *always* set, even for alternate entry
# points and when $wgout gets disabled or overridden.
php代码 
header( 'x-content-type-options: nosniff' );  针对ie8进行关闭内容嗅探,大家应该应该忽略这个
php代码 
$wgrequesttime = microtime( true );  函数返回当前 unix 时间戳和微秒数。
php代码 
unset( $ip );  注销定义$ip的变量
php代码 
define( 'mediawiki', true );  定义一个常量mediawiki
# full path to working directory.
# makes it possible to for example to have effective exclude path in apc.
# __dir__ breaks symlinked includes, but realpath() returns false
# if we don't have permissions on parent directories.
php代码 
$ip = getenv( 'mw_install_path' );  if ( $ip === false ) {  $ip = realpath( '.' ) ?: dirname( __dir__ );  }  通过获取php的环境变量,获取安装的安装目录。
# load the profiler
php代码 
require_once$ip/includes/profiler/profiler.php;  $wgrustart = wfgetrusage() ?: array();  ...
# start the profiler
//startprofiler.php文件里只调用了profilerstub.php。根据上下文来看profilerstub.php里定义的两个主要的函数wfprofilein()、wfprofileout()应该是做debug用的。
php代码 
$wgprofiler = array();  if ( file_exists( $ip/startprofiler.php ) ) {  require$ip/startprofiler.php;  }  ...  if ( !defined( 'mw_no_setup' ) ) {  require_once$ip/includes/setup.php;  }  
require_once了一大堆文件:profiler.php(分析其,主要用于debug调试使用)、autoloader.php(类管理器,类似java中spring的ioc容器)、defines.php、startprofiler.php、defaultsettings.php、autoload.php、nolocalsettings.php、outputhandler.php、setup.php……
接下来到了程序业务处理入口:
php代码 
$mediawiki = new mediawiki();  $mediawiki->run();  mediawiki.php
mediawiki.php里定义了mediawiki类。其中包括很多的wiki对象的方法。接着为$mediawiki对象开辟内存空间。
php代码 
publicfunction __construct( icontextsource $context = null ) {  if ( !$context ) {  $context = requestcontext::getmain();  }  $this->context = $context;  $this->config = $context->getconfig();  }  通过构造方法,获取request请求对象、配置信息。
php代码 
publicfunction run() {  try {  //请求中如果包含延迟请求,和系统最后一次操作时间对比。如果最后一次操作时间大于请求最大延迟,则提示超时。$this->checkmaxlag();  try {  //关键方法,主要做业务流转相关操作。$this->main();  } catch ( errorpageerror $e ) {  // bug 62091: while exceptions are convenient to bubble up gui errors,// they are not internal application faults. as with normal requests, this// should commit, print the output, do deferred updates, jobs, and profiling.wfgetlbfactory()->commitmasterchanges();  $e->report(); // display the gui error}  if ( function_exists( 'fastcgi_finish_request' ) ) {  fastcgi_finish_request();  }  $this->triggerjobs();  $this->restinpeace();  } catch ( exception $e ) {  mwexceptionhandler::handle( $e );  }  }  现在进入关键方法main()方法  // send ajax requests to the ajax dispatcher.if ( $this->config->get( 'useajax' ) && $request->getval( 'action', 'view' ) == 'ajax' ) {  // set a dummy title, because $wgtitle == null might break things$title = title::maketitle( ns_main, 'ajax' );  $this->context->settitle( $title );  $wgtitle = $title;  $dispatcher = new ajaxdispatcher( $this->config );  $dispatcher->performaction( $this->context->getuser() );  wfprofileout( __method__ );  return;  }  判断是否启用ajax请求,并且请求中$action值为ajax,则将ajax请求发送到ajax dispather处理器。
if the user has forcehttps set to true, or if the user
// is in a group requiring https, or if they have the https
// preference set, redirect them to https.
// note: do this after $wgtitle is setup, otherwise the hooks run from
// isloggedin() will do all sorts of weird stuff.
php代码 
if (  $request->getprotocol() == 'http' &&  (  ...  wfprofileout( __method__ );  return;  }  }  如果forcehttps设置为true,并且使用https访问,进行重定项处理
php代码 
if ( $this->config->get( 'usefilecache' ) && $title->getnamespace() >= 0 ) {  wfprofilein( 'main-try-filecache' );  ...  wfprofileout( 'main-try-filecache' );  }  判断配置是否开启文件缓存功能,并且命名空间大于等于1的情况,使用文件缓存机制相关功能。
命名空间值
命名空间值含义
-1
special:
0
template:
1
talk:
2
user:
3
user_talk:
4
test:
5
test_talk:
6
image:
7
image_talk:
8
mediawiki:
9
mediawiki_talk:
10
template:
11
template_talk:
12
help:
13
help_talk:
14
category:
15
category_talk:
16
onlinepay
// actually do the work of the request and build up any output
php代码 
$this->performrequest();  处理请求的工作和建立输出。在此方法会生程一个输出对象$output,此对象有相应方法可以设置不同的输出结果。
php代码 
wfprofilein( __method__ );  方法第一句,发现mediawiki中基本方法入口都要这么一句,他的后面出现wfprofileout( __method__ )跟踪发现为启动debug模式后,进行相应数据的打印。开启打印方法locationsettings.php里设置$wgdebuglogfile=d:\a.txt值。注意:wfprofilein和wfprofileout需要成对出现,否则会出错。而且调试信息的输出顺序是:先输出已经匹配好了的一对wfprofilein和wfprofileout的调试信息,也即遇到wfprofileout时才输出该段调试信息,而不是wfprofilein。。
php代码 
if ( $request->getval( 'printable' ) === 'yes' ) {  $output->setprintable();  }  判断请求是否有打印请求。如果有就在输出对象中进行标注。
php代码 
$unused = null; // to pass it by referencewfrunhooks( 'beforeinitialize', array( &$title, &$unused, &$output, &$user, $request, $this ) );  通过请求对象,进行初始化之前的检查工作。这个属于系统钩子程序,应该需要插件进行实现beforeinitialize方法,我全文搜索没有此方法的具体实用。
// check user's permissions to read this page.
// we have to check here to catch special pages etc.
// we will check again in article::view().
php代码 
$permerrors = $title->isspecial( 'runjobs' )  ? array() // relies on hmac key signature alone: $title->getuserpermissionserrors( 'read', $user );  if ( count( $permerrors ) ) {  根据title进行判断用户是否有次页面的访问read权限。如果权限不足构造项页面进行返回。
// either all db and deferred updates should happen or none.
// the later should not be cancelled due to client disconnect.
php代码 
ignore_user_abort( true );  php提供的函数,如果设置为 true,则忽略与用户的断开。php 不会检测到用户是否已断开连接,直到尝试向客户机发送信息为止。
// now commit any transactions, so that unreported errors after
// output() don't roll back the whole db transaction
php代码 
wfgetlbfactory()->commitmasterchanges();  事物提交,存在错误进行回滚。
// output everything!
php代码 
$this->context->getoutput()->output();  页面输出到前台页面,在此句之前所有数据不携带样式。词句代码执行会按返回数据类型进行添加不同的skin。
php代码 
wfprofileout( __method__ );   以上就介绍了mediawiki1.24源码分析(一) ,包括了方面的内容,希望对php教程有兴趣的朋友有所帮助。
其它类似信息

推荐信息