PHPCMS V9 框架代碼分析(入口程序)


  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.

順序 選擇 循環 總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM