所有分析說明採用文字使用淺紅色、小四號楷體。
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' ) < 0 ) {
- // 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 reference
- wfRunHooks( '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教程有興趣的朋友有所協助。