PHPCMS V9 框架代码分析(入口程序)
PHPCMS是采用MVC設(shè)計模式開發(fā),基于模塊和操作的方式進(jìn)行訪問,采用單一入口模式進(jìn)行項目部署和訪問,無論訪問任何一個模塊或者功能,只有一個統(tǒng)一的入口。
入口程序是在前期處理用戶請求的引導(dǎo)程序。它是唯一一個可以被最終用戶直接請求運(yùn)行的。
PHPCMS?V9的入口程序(index.php)如下:
1 <?php 2 /** 3 * index.php PHPCMS 入口 4 * 5 * @copyright (C) 2005-2010 PHPCMS 6 * @license http://www.phpcms.cn/license/ 7 * @lastmodify 2010-6-1 8 */ 9 //PHPCMS根目錄 10 11 define('PHPCMS_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR); 12 13 include PHPCMS_PATH.'/phpcms/base.php'; 14 15 pc_base::creat_app(); 16 17 ?>第一行:定義項目的根路徑,后面文件查找依賴此變量。
DIRECTORY_SEPARATOR(目錄分隔符)是一個返回與操作系統(tǒng)相關(guān)的路徑分隔符的內(nèi)置命令,不需要任何定義與包含即可直接使用。由于windows上習(xí)慣性的使用\作為文件分隔符,但是在linux上人家是不認(rèn)識這個標(biāo)識的,人家只認(rèn)識/,于是就要引入下面這個php內(nèi)置常量:DIRECTORY_SEPARATOR。
第二行:根據(jù)項目根路徑引入base.php文件,文件內(nèi)容如下:
1 <?php 2 /** 3 * base.php PHPCMS框架入口文件 4 * 5 * @copyright (C) 2005-2010 PHPCMS 6 * @license http://www.phpcms.cn/license/ 7 * @lastmodify 2010-6-7 8 */ 9 10 /* 11 * 定義常量IN_PHPCMS 12 */ 13 // 定義常量IN_PHPCMS 14 define('IN_PHPCMS', true); 15 16 /* 17 * 定義PHPCMS框架路徑、緩存文件夾地址 18 */ 19 //PHPCMS框架路徑 20 define('PC_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR); 21 if(!defined('PHPCMS_PATH')) define('PHPCMS_PATH', PC_PATH.'..'.DIRECTORY_SEPARATOR); 22 23 //緩存文件夾地址 24 define('CACHE_PATH', PHPCMS_PATH.'caches'.DIRECTORY_SEPARATOR); 25 26 /* 27 * 主機(jī)協(xié)議、當(dāng)前訪問的主機(jī)名、來源、系統(tǒng)開始時間 28 */ 29 //主機(jī)協(xié)議 30 define('SITE_PROTOCOL', isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://'); 31 32 //當(dāng)前訪問的主機(jī)名 33 define('SITE_URL', (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '')); 34 35 //來源 36 define('HTTP_REFERER', isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''); 37 38 //系統(tǒng)開始時間 39 define('SYS_START_TIME', microtime()); 40 41 /* 42 * 加載共用函數(shù)庫 43 */ 44 //加載公用函數(shù)庫 45 pc_base::load_sys_func('global'); 46 pc_base::load_sys_func('extention'); 47 pc_base::auto_load_func(); 48 49 /* 50 * 加載一些配置參數(shù) 51 */ 52 pc_base::load_config('system','errorlog') ? set_error_handler('my_error_handler') : error_reporting(E_ERROR | E_WARNING | E_PARSE); 53 54 //設(shè)置本地時差 55 function_exists('date_default_timezone_set') && date_default_timezone_set(pc_base::load_config('system','timezone')); 56 57 define('CHARSET' ,pc_base::load_config('system','charset')); 58 //輸出頁面字符集 59 header('Content-type: text/html; charset='.CHARSET); 60 61 define('SYS_TIME', time()); 62 //定義網(wǎng)站根路徑 63 define('WEB_PATH',pc_base::load_config('system','web_path')); 64 //js 路徑 65 define('JS_PATH',pc_base::load_config('system','js_path')); 66 //css 路徑 67 define('CSS_PATH',pc_base::load_config('system','css_path')); 68 //img 路徑 69 define('IMG_PATH',pc_base::load_config('system','img_path')); 70 //動態(tài)程序路徑 71 define('APP_PATH',pc_base::load_config('system','app_path')); 72 73 //應(yīng)用靜態(tài)文件路徑 74 define('PLUGIN_STATICS_PATH',WEB_PATH.'statics/plugin/'); 75 76 if(pc_base::load_config('system','gzip') && function_exists('ob_gzhandler')) 77 { 78 ob_start('ob_gzhandler'); 79 } 80 else 81 { 82 ob_start(); 83 } 84 85 class pc_base 86 { 87 /** 88 * 初始化應(yīng)用程序 89 */ 90 public static function creat_app() 91 { 92 return self::load_sys_class('application'); 93 } 94 /** 95 * 加載系統(tǒng)類方法 96 * @param string $classname 類名 97 * @param string $path 擴(kuò)展地址 98 * @param intger $initialize 是否初始化 99 */ 100 public static function load_sys_class($classname, $path = '', $initialize = 1) 101 { 102 return self::_load_class($classname, $path, $initialize); 103 } 104 105 /** 106 * 加載應(yīng)用類方法 107 * @param string $classname 類名 108 * @param string $m 模塊 109 * @param intger $initialize 是否初始化 110 */ 111 public static function load_app_class($classname, $m = '', $initialize = 1) 112 { 113 $m = empty($m) && defined('ROUTE_M') ? ROUTE_M : $m; 114 if (empty($m)) 115 return false; 116 return self::_load_class($classname, 'modules'.DIRECTORY_SEPARATOR.$m.DIRECTORY_SEPARATOR.'classes', $initialize); 117 } 118 119 /** 120 * 加載數(shù)據(jù)模型 121 * @param string $classname 類名 122 */ 123 public static function load_model($classname) 124 { 125 return self::_load_class($classname,'model'); 126 } 127 128 /** 129 * 加載類文件函數(shù) 130 * @param string $classname 類名 131 * @param string $path 擴(kuò)展地址 132 * @param intger $initialize 是否初始化 133 */ 134 private static function _load_class($classname, $path = '', $initialize = 1) 135 { 136 static $classes = array(); 137 if (empty($path)) 138 $path = 'libs'.DIRECTORY_SEPARATOR.'classes'; 139 140 $key = md5($path.$classname); 141 if (isset($classes[$key])) 142 { 143 if (!empty($classes[$key])) 144 { 145 return $classes[$key]; 146 } 147 else 148 { 149 return true; 150 } 151 } 152 if (file_exists(PC_PATH.$path.DIRECTORY_SEPARATOR.$classname.'.class.php')) 153 { 154 include PC_PATH.$path.DIRECTORY_SEPARATOR.$classname.'.class.php'; 155 $name = $classname; 156 if ($my_path = self::my_path(PC_PATH.$path.DIRECTORY_SEPARATOR.$classname.'.class.php')) 157 { 158 include $my_path; 159 $name = 'MY_'.$classname; 160 } 161 if ($initialize) 162 { 163 $classes[$key] = new $name; 164 } 165 else 166 { 167 $classes[$key] = true; 168 } 169 170 return $classes[$key]; 171 } 172 else 173 { 174 return false; 175 } 176 } 177 178 /** 179 * 加載系統(tǒng)的函數(shù)庫 180 * @param string $func 函數(shù)庫名 181 */ 182 public static function load_sys_func($func) 183 { 184 return self::_load_func($func); 185 } 186 187 /** 188 * 自動加載autoload目錄下函數(shù)庫 189 * @param string $func 函數(shù)庫名 190 */ 191 public static function auto_load_func($path='') 192 { 193 return self::_auto_load_func($path); 194 } 195 196 /** 197 * 加載應(yīng)用函數(shù)庫 198 * @param string $func 函數(shù)庫名 199 * @param string $m 模型名 200 */ 201 public static function load_app_func($func, $m = '') 202 { 203 $m = empty($m) && defined('ROUTE_M') ? ROUTE_M : $m; 204 if (empty($m)) 205 return false; 206 return self::_load_func($func, 'modules'.DIRECTORY_SEPARATOR.$m.DIRECTORY_SEPARATOR.'functions'); 207 } 208 209 /** 210 * 加載插件類庫 211 */ 212 public static function load_plugin_class($classname, $identification = '' ,$initialize = 1) 213 { 214 $identification = empty($identification) && defined('PLUGIN_ID') ? PLUGIN_ID : $identification; 215 if (empty($identification)) 216 return false; 217 return pc_base::load_sys_class($classname, 'plugin'.DIRECTORY_SEPARATOR.$identification.DIRECTORY_SEPARATOR.'classes', $initialize); 218 } 219 220 /** 221 * 加載插件函數(shù)庫 222 * @param string $func 函數(shù)文件名稱 223 * @param string $identification 插件標(biāo)識 224 */ 225 public static function load_plugin_func($func,$identification) 226 { 227 static $funcs = array(); 228 $identification = empty($identification) && defined('PLUGIN_ID') ? PLUGIN_ID : $identification; 229 if (empty($identification)) 230 return false; 231 $path = 'plugin'.DIRECTORY_SEPARATOR.$identification.DIRECTORY_SEPARATOR.'functions'.DIRECTORY_SEPARATOR.$func.'.func.php'; 232 $key = md5($path); 233 if (isset($funcs[$key])) 234 return true; 235 if (file_exists(PC_PATH.$path)) 236 { 237 include PC_PATH.$path; 238 } 239 else 240 { 241 $funcs[$key] = false; 242 return false; 243 } 244 $funcs[$key] = true; 245 return true; 246 } 247 248 /** 249 * 加載插件數(shù)據(jù)模型 250 * @param string $classname 類名 251 */ 252 public static function load_plugin_model($classname, $identification) 253 { 254 $identification = empty($identification) && defined('PLUGIN_ID') ? PLUGIN_ID : $identification; 255 $path = 'plugin'.DIRECTORY_SEPARATOR.$identification.DIRECTORY_SEPARATOR.'model'; 256 return self::_load_class($classname,$path); 257 } 258 259 /** 260 * 加載函數(shù)庫 261 * @param string $func 函數(shù)庫名 262 * @param string $path 地址 263 */ 264 private static function _load_func($func, $path = '') 265 { 266 static $funcs = array(); 267 if (empty($path)) $path = 'libs'.DIRECTORY_SEPARATOR.'functions'; 268 $path .= DIRECTORY_SEPARATOR.$func.'.func.php'; 269 $key = md5($path); 270 if (isset($funcs[$key])) 271 return true; 272 if (file_exists(PC_PATH.$path)) 273 { 274 include PC_PATH.$path; 275 } 276 else 277 { 278 $funcs[$key] = false; 279 return false; 280 } 281 $funcs[$key] = true; 282 return true; 283 } 284 285 /** 286 * 加載函數(shù)庫 287 * @param string $func 函數(shù)庫名 288 * @param string $path 地址 289 */ 290 private static function _auto_load_func($path = '') 291 { 292 if (empty($path)) $path = 'libs'.DIRECTORY_SEPARATOR.'functions'.DIRECTORY_SEPARATOR.'autoload'; 293 $path .= DIRECTORY_SEPARATOR.'*.func.php'; 294 $auto_funcs = glob(PC_PATH.DIRECTORY_SEPARATOR.$path); 295 if(!empty($auto_funcs) && is_array($auto_funcs)) 296 { 297 foreach($auto_funcs as $func_path) 298 { 299 include $func_path; 300 } 301 } 302 } 303 /** 304 * 是否有自己的擴(kuò)展文件 305 * @param string $filepath 路徑 306 */ 307 public static function my_path($filepath) 308 { 309 $path = pathinfo($filepath); 310 if (file_exists($path['dirname'].DIRECTORY_SEPARATOR.'MY_'.$path['basename'])) 311 { 312 return $path['dirname'].DIRECTORY_SEPARATOR.'MY_'.$path['basename']; 313 } 314 else 315 { 316 return false; 317 } 318 } 319 320 /** 321 * 加載配置文件 322 * @param string $file 配置文件 323 * @param string $key 要獲取的配置鍵 324 * @param string $default 默認(rèn)配置。當(dāng)獲取配置項目失敗時該值發(fā)生作用。 325 * @param boolean $reload 強(qiáng)制重新加載。 326 */ 327 public static function load_config($file, $key = '', $default = '', $reload = false) 328 { 329 static $configs = array(); 330 if (!$reload && isset($configs[$file])) 331 { 332 if (empty($key)) 333 { 334 return $configs[$file]; 335 } 336 elseif (isset($configs[$file][$key])) 337 { 338 return $configs[$file][$key]; 339 } 340 else 341 { 342 return $default; 343 } 344 } 345 $path = CACHE_PATH.'configs'.DIRECTORY_SEPARATOR.$file.'.php'; 346 if (file_exists($path)) 347 { 348 $configs[$file] = include $path; 349 } 350 if (empty($key)) 351 { 352 return $configs[$file]; 353 } 354 else if (isset($configs[$file][$key])) 355 { 356 return $configs[$file][$key]; 357 } 358 else 359 { 360 return $default; 361 } 362 } 363 }base.php文件為框架入口文件,包含實(shí)例化系統(tǒng)/模塊類方法,調(diào)用系統(tǒng)/模塊方法,系統(tǒng)常用常量等。為了便于理解,現(xiàn)按順序分四部分解析:
[1] 定義常量?IN_PHPCMS
define('IN_PHPCMS', true);在phpcms項目源碼搜索關(guān)鍵字“IN_PHPCMS”,相關(guān)的代碼語句有:
defined(‘IN_PHPCMS’) or exit('No permission resources.');以及:
defined('IN_PHPCMS') or exit('Access Denied.');defined:是用來檢查常量是否已定義。
注意:如果你要檢查一個變量是否存在,請使用isset()。如果你要檢查一個函數(shù)是否存在,使用function_exists()。defined()函數(shù)僅對constants常量有效:如果該名稱的常量已定義,返回TURE;未定義則返回FALSE。
or:如果or前面的代碼語句執(zhí)行失敗(或者返回false、0、null),那么執(zhí)行or到其后第一個分號前面的代碼(但雙引號的分號不算);如果or前面的代碼執(zhí)行成功(或者返回true、非0、非null),那么不執(zhí)行or到其后第一個分號前面的代碼。
綜上所述,phpcms為了代碼不執(zhí)行錯誤,每個執(zhí)行文件都會判斷是否包含了base.php文件,以減少錯誤。
[2] 定義PHPCMS框架路徑、緩存文件夾地址
具體代碼片段見上文base.php文件代碼詳細(xì)
__FILE__?返回文件的完整路徑和文件名。如果用在被包含文件中,則返回被包含的文件名。
__FILE__?總是包含一個絕對路徑(如果是符號連接,則是解析后的絕對路徑,比如PHPCMS里面的?PC_PATH.’..’.DIRECTORY_SEPARATOR)
dirname(__FILE__)?函數(shù)返回的是腳本所在的路徑,不會返回當(dāng)前的文件名稱。如果b.php包含了dirname(__FILE__)相關(guān)代碼,同時b.php被其他目錄里的a.php文件require或者include已用的話,返回的依然是b.php所在的那個文件夾路徑,而不是變成a.php文件所在目錄。
[3] 主機(jī)協(xié)議、當(dāng)前訪問的主機(jī)名、來源、系統(tǒng)開始時間
$_SERVER['SERVER_PORT']:返回80是使用http協(xié)議訪問
$_SERVER['SERVER_PORT']:返回443是使用https協(xié)議訪問
[4] 加載共用函數(shù)庫
1 //加載公用函數(shù)庫 2 pc_base::load_sys_func('global'); 3 pc_base::load_sys_func('extention'); 4 pc_base::auto_load_func();很顯然,類中靜態(tài)方法調(diào)用,具體執(zhí)行步驟見類pc_base(上文base.php文件中)的函數(shù)。
頭兩句分別加載了/phpcms/libs/functions/global.func.php 和 /phpcms/libs/functions/extention.func.php文件。
global.func.php是共用函數(shù)庫。
extension.func.php是用戶自定義函數(shù)庫。
最后一句是加載/phpcms/libs/functions/autoload/文件夾下面?*.func.php?文件(詳見函數(shù)注釋)。
?
第三行:pc_base是base.php定義的類,調(diào)用類方法create_app。
?
Good Good Study, Day? Day? Up.
順序 選擇 循環(huán) 總結(jié)
總結(jié)
以上是生活随笔為你收集整理的PHPCMS V9 框架代码分析(入口程序)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Solr在Weblogic中部署遇到的问
- 下一篇: Flex 布局教程:实例篇