zoukankan      html  css  js  c++  java
  • 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.

    顺序 选择 循环 总结

  • 相关阅读:
    修改数据库的兼容级别
    如何写出安全的API接口
    最新IP地址数据库
    java 中的静态(static)代码块
    Java RTTI(类型信息)(.class 类对象)
    机器学习之决策树预测——泰坦尼克号乘客数据实例
    敏捷开发 —— TDD(测试驱动开发)
    Java 内存泄漏
    红顶商人 —— 胡雪岩
    各地特色美食与点菜的艺术
  • 原文地址:https://www.cnblogs.com/Braveliu/p/5091424.html
Copyright © 2011-2022 走看看