PHPCMS是采用MVC設計模式開發,基於模塊和操作的方式進行訪問,采用單一入口模式進行項目部署和訪問,無論訪問任何一個模塊或者功能,只有一個統一的入口。
入口程序是在前期處理用戶請求的引導程序。它是唯一一個可以被最終用戶直接請求運行的。
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(目錄分隔符)是一個返回與操作系統相關的路徑分隔符的內置命令,不需要任何定義與包含即可直接使用。由於windows上習慣性的使用\作為文件分隔符,但是在linux上人家是不認識這個標識的,人家只認識/,於是就要引入下面這個php內置常量:DIRECTORY_SEPARATOR。
第二行:根據項目根路徑引入base.php文件,文件內容如下:
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 * 主機協議、當前訪問的主機名、來源、系統開始時間 28 */ 29 //主機協議 30 define('SITE_PROTOCOL', isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://'); 31 32 //當前訪問的主機名 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 //系統開始時間 39 define('SYS_START_TIME', microtime()); 40 41 /* 42 * 加載共用函數庫 43 */ 44 //加載公用函數庫 45 pc_base::load_sys_func('global'); 46 pc_base::load_sys_func('extention'); 47 pc_base::auto_load_func(); 48 49 /* 50 * 加載一些配置參數 51 */ 52 pc_base::load_config('system','errorlog') ? set_error_handler('my_error_handler') : error_reporting(E_ERROR | E_WARNING | E_PARSE); 53 54 //設置本地時差 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 //定義網站根路徑 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 //動態程序路徑 71 define('APP_PATH',pc_base::load_config('system','app_path')); 72 73 //應用靜態文件路徑 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 * 初始化應用程序 89 */ 90 public static function creat_app() 91 { 92 return self::load_sys_class('application'); 93 } 94 /** 95 * 加載系統類方法 96 * @param string $classname 類名 97 * @param string $path 擴展地址 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 * 加載應用類方法 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 * 加載數據模型 121 * @param string $classname 類名 122 */ 123 public static function load_model($classname) 124 { 125 return self::_load_class($classname,'model'); 126 } 127 128 /** 129 * 加載類文件函數 130 * @param string $classname 類名 131 * @param string $path 擴展地址 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 * 加載系統的函數庫 180 * @param string $func 函數庫名 181 */ 182 public static function load_sys_func($func) 183 { 184 return self::_load_func($func); 185 } 186 187 /** 188 * 自動加載autoload目錄下函數庫 189 * @param string $func 函數庫名 190 */ 191 public static function auto_load_func($path='') 192 { 193 return self::_auto_load_func($path); 194 } 195 196 /** 197 * 加載應用函數庫 198 * @param string $func 函數庫名 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 * 加載插件函數庫 222 * @param string $func 函數文件名稱 223 * @param string $identification 插件標識 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 * 加載插件數據模型 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 * 加載函數庫 261 * @param string $func 函數庫名 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 * 加載函數庫 287 * @param string $func 函數庫名 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 * 是否有自己的擴展文件 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 默認配置。當獲取配置項目失敗時該值發生作用。 325 * @param boolean $reload 強制重新加載。 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文件為框架入口文件,包含實例化系統/模塊類方法,調用系統/模塊方法,系統常用常量等。為了便於理解,現按順序分四部分解析:
[1] 定義常量 IN_PHPCMS
define('IN_PHPCMS', true);
在phpcms項目源碼搜索關鍵字“IN_PHPCMS”,相關的代碼語句有:
defined(‘IN_PHPCMS’) or exit('No permission resources.');
以及:
defined('IN_PHPCMS') or exit('Access Denied.');
defined:是用來檢查常量是否已定義。
注意:如果你要檢查一個變量是否存在,請使用isset()。如果你要檢查一個函數是否存在,使用function_exists()。defined()函數僅對constants常量有效:如果該名稱的常量已定義,返回TURE;未定義則返回FALSE。
or:如果or前面的代碼語句執行失敗(或者返回false、0、null),那么執行or到其后第一個分號前面的代碼(但雙引號的分號不算);如果or前面的代碼執行成功(或者返回true、非0、非null),那么不執行or到其后第一個分號前面的代碼。
綜上所述,phpcms為了代碼不執行錯誤,每個執行文件都會判斷是否包含了base.php文件,以減少錯誤。
[2] 定義PHPCMS框架路徑、緩存文件夾地址
具體代碼片段見上文base.php文件代碼詳細
__FILE__ 返回文件的完整路徑和文件名。如果用在被包含文件中,則返回被包含的文件名。
__FILE__ 總是包含一個絕對路徑(如果是符號連接,則是解析后的絕對路徑,比如PHPCMS里面的 PC_PATH.’..’.DIRECTORY_SEPARATOR)
dirname(__FILE__) 函數返回的是腳本所在的路徑,不會返回當前的文件名稱。如果b.php包含了dirname(__FILE__)相關代碼,同時b.php被其他目錄里的a.php文件require或者include已用的話,返回的依然是b.php所在的那個文件夾路徑,而不是變成a.php文件所在目錄。
[3] 主機協議、當前訪問的主機名、來源、系統開始時間
$_SERVER['SERVER_PORT']:返回80是使用http協議訪問
$_SERVER['SERVER_PORT']:返回443是使用https協議訪問
[4] 加載共用函數庫
1 //加載公用函數庫 2 pc_base::load_sys_func('global'); 3 pc_base::load_sys_func('extention'); 4 pc_base::auto_load_func();
很顯然,類中靜態方法調用,具體執行步驟見類pc_base(上文base.php文件中)的函數。
頭兩句分別加載了/phpcms/libs/functions/global.func.php 和 /phpcms/libs/functions/extention.func.php文件。
global.func.php是共用函數庫。
extension.func.php是用戶自定義函數庫。
最后一句是加載/phpcms/libs/functions/autoload/文件夾下面 *.func.php 文件(詳見函數注釋)。
第三行:pc_base是base.php定義的類,調用類方法create_app。
Good Good Study, Day Day Up.
順序 選擇 循環 總結