phpcms单入口源码分析

时间:2024.4.2

PHPCMS单入口源码分析

本人在查阅PHP相关单入口资料时发现文献很少,而且PHPCMS源码的官方注释也十分有限,所以在此简要的写一篇关于PHPCMS单入口源码的分析,此文给出了PHPCMS入口的主要源码附带本人的一些注释。

限于本人的个人水平和疏忽,不能保证文章内的源码注释绝对准确,适合新手朋友学习 交流之用。

话不多说,首先我们需要下载一个PHPCMS的内容管理系统并安装,相关的下载安装教程百度上很多,在此不再赘述了。

安装完成后我们打开安装的PHPCMS工程,打开index.php,这是默认的控制器,也就是唯一的入口了。

该文件内的代码很少,详细如下:

/**

* index.php PHPCMS 入口

*/

define('PHPCMS_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR);

includePHPCMS_PATH.'/phpcms/base.php';

pc_base::creat_app();

该文件定义了一个常量后就引入了一个名为base.php的文件,然后调用该文件中pc_base类的静态方法,创建一个应用。

我们打开安装文件目录下/phpcms/base.php源码附带注释如下: <?php

/**

* base.php PHPCMS框架入口文件

*/

//设定入口为true

define('IN_PHPCMS', true);

// 设定PC_PATH:PHPCMS框架路径

define('PC_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR);

if(!defined('PHPCMS_PATH'))

define('PHPCMS_PATH',PC_PATH.'..'.DIRECTORY_SEPARATOR);

//设定CACHE_PATH:缓存路径

define('CACHE_PATH', PHPCMS_PATH.'caches'.DIRECTORY_SEPARATOR);

//设定SITE_PROTOCOL:主机协议

define('SITE_PROTOCOL', isset($_SERVER['SERVER_PORT'])

&&$_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://');

//设定SITE_URL:当前访问的主机名

define('SITE_URL', (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ''));

//设定HTTP_REFERER:来源

define('HTTP_REFERER', isset($_SERVER['HTTP_REFERER']) ?

$_SERVER['HTTP_REFERER'] : '');

//设定SYS_START_TIME:系统开始时间

define('SYS_START_TIME', microtime());

//加载公用函数库

pc_base::load_sys_func('global');

pc_base::load_sys_func('extention');

pc_base::auto_load_func();

//加载错误日志、报告、句柄

pc_base::load_config('system','errorlog') ?

set_error_handler('my_error_handler') : error_reporting(E_ERROR | E_WARNING | E_PARSE);

//设置本地时差

function_exists('date_default_timezone_set')

&&date_default_timezone_set(pc_base::load_config('system','timezone')); define('CHARSET',pc_base::load_config('system','charset'));

//输出页面字符集

header('Content-type: text/html; charset='.CHARSET);

//返回当前unix时间戳

define('SYS_TIME', time());

//定义网站根路径

define('WEB_PATH',pc_base::load_config('system','web_path'));

//js路径

define('JS_PATH',pc_base::load_config('system','js_path'));

//css路径

define('CSS_PATH',pc_base::load_config('system','css_path'));

//img路径

define('IMG_PATH',pc_base::load_config('system','img_path'));

//动态程序路径

define('APP_PATH',pc_base::load_config('system','app_path'));

//应用静态文件路径

define('PLUGIN_STATICS_PATH',WEB_PATH.'statics/plugin/');

if(pc_base::load_config('system','gzip') &&function_exists('ob_gzhandler')) {

}

classpc_base {

{

$m= empty($m) &&defined('ROUTE_M') ? ROUTE_M :$m; if(empty($m)) return false; return self::_load_class($classname, /** * 初始化应用程序 * creat_app()不仅包含了application.class.php文件,还返回了一个该类的实例 */ public static function creat_app() { } /** * 加载系统类方法 * @param string $classname类名 * @param string $path 扩展地址 * @paramintger $initialize 是否初始化 *///默认path路径为libs/classes public static function load_sys_class($classname, $path= '', $initialize= } /** * 加载应用类方法 * @param string $classname类名 * @param string $m 模块 * @paramintger $initialize 是否初始化 */ public static function load_app_class($classname, $m= '', $initialize= 1) return self::_load_class($classname, $path, $initialize); return self::load_sys_class('application'); ob_start('ob_gzhandler'); ob_start(); } else { 1) {

'modules'.DIRECTORY_SEPARATOR.$m.DIRECTORY_SEPARATOR.'classes',

$initialize);

} /**

{

* 加载数据模型 * @param string $classname类名 */ public static function load_model($classname) { } /** * 加载类文件函数 * @param string $classname类名 * @param string $path 扩展地址 * @paramintger $initialize 是否初始化 */ private static function _load_class($classname, $path= '', $initialize= 1) //如果path为空,指定path路径为libs/classes static$classes = array(); if(empty($path)) $path= 'libs'.DIRECTORY_SEPARATOR.'classes'; $key = md5($path.$classname); if(isset($classes[$key])) { } /** * 如果存在phpcms/$path/$classname.class.php则包含 */ if(!empty($classes[$key])) { } return$classes[$key]; return true; } else { return self::_load_class($classname,'model'); //返回加密后的类具体路径给数组的索引 if(file_exists(PC_PATH.$path.DIRECTORY_SEPARATOR.$classname.'.class.php includePC_PATH.$path.DIRECTORY_SEPARATOR.$classname.'.class.php'; $name = $classname; //如果此路径下有扩展路径(自定义)//覆盖原$path用自定义$path ')) { phpcms/$path/'MY_'.$classname.class.php便引入 if($my_path= include$my_path; //覆盖原类名,用自定义的 $name = 'MY_'.$classname; self::my_path(PC_PATH.$path.DIRECTORY_SEPARATOR.$classname.'.class.php')) {

} } } if($initialize) { } return$classes[$key]; return false; $classes[$key] = new $name; //返回文件名类定义类的实例 $classes[$key] = true; } else { } else { /** * 加载系统的函数库 * @param string $func函数库名 */ public static function load_sys_func($func) { } /** * 自动加载autoload目录下函数库 * @param string $func函数库名 */ public static function auto_load_func($path='') { } /** * 加载应用函数库 * @param string $func函数库名 * @param string $m 模型名 */ public static function load_app_func($func, $m= '') { } /** * 加载插件类库

*@$identification插件标识 $m= empty($m) &&defined('ROUTE_M') ? ROUTE_M :$m; if(empty($m)) return false; return self::_load_func($func, return self::_auto_load_func($path); return self::_load_func($func); //判断模块是否为空,常量是否定义 'modules'.DIRECTORY_SEPARATOR.$m.DIRECTORY_SEPARATOR.'functions');

*/ public static function load_plugin_class($classname, $identification= '' ,$initialize= 1) {

//判断插件标识是否为空,判断是否定义插件id

$identification= empty($identification) &&defined('PLUGIN_ID') ? if(empty($identification)) return false; returnpc_base::load_sys_class($classname, PLUGIN_ID :$identification; //调用load_sys_class函数

'plugin'.DIRECTORY_SEPARATOR.$identification.DIRECTORY_SEPARATOR.'classes', $initialize);

} /** * 加载插件函数库 * @param string $func函数文件名称 * @param string $identification 插件标识 */ public static function load_plugin_func($func,$identification) { static$funcs= array(); $identification= empty($identification) &&defined('PLUGIN_ID') ? if(empty($identification)) return false; PLUGIN_ID :$identification;

$path =

'plugin'.DIRECTORY_SEPARATOR.$identification.DIRECTORY_SEPARATOR.'functions'.DIRECTORY_SEPARATOR.$func.'.func.php';

//将路径加密后作为数组的索引

} /** * 加载插件数据模型 * @param string $classname类名 */ public static function load_plugin_model($classname,$identification) { $key = md5($path); if(isset($funcs[$key])) return true; if(file_exists(PC_PATH.$path)) { } $funcs[$key] = true; return true; includePC_PATH.$path; $funcs[$key] = false; return false; } else {

} $identification= empty($identification) &&defined('PLUGIN_ID') ? $path = return self::_load_class($classname,$path); PLUGIN_ID :$identification; 'plugin'.DIRECTORY_SEPARATOR.$identification.DIRECTORY_SEPARATOR.'model'; /** * 加载指定函数 * @param string $func函数名 * @param string $path 地址 */ private static function _load_func($func, $path= '') { } /** * 加载函数库 * @param string $func函数库名 * @param string $path 数组路径 */ private static function _auto_load_func($path= '') { /** * 如果path为空,则使用默认path中所有.func.php结尾的函数库(默认static$funcs= array(); /* * 如果没有指定位置,默认叠加为phpcms/libs/下的某一位置 */ if(empty($path)) $path= 'libs'.DIRECTORY_SEPARATOR.'functions'; $path.=DIRECTORY_SEPARATOR.$func.'.func.php'; $key = md5($path); if(isset($funcs[$key])) return true; /* * 如果存在文件,则包含,否则func[$key]为false */ if(file_exists(PC_PATH.$path)) { } $funcs[$key] = true; return true; includePC_PATH.$path; $funcs[$key] = false; return false; } else {

libs/functions/autoload/*.func.php) */

} /** if(empty($path)) $path= $path.=DIRECTORY_SEPARATOR.'*.func.php'; /** * 返回path包含的函数库文件,组成数组,遍历数组后包含 */ $auto_funcs=array(); $auto_funcs = glob(PC_PATH.DIRECTORY_SEPARATOR.$path); } foreach($auto_funcs as $func_path) { } include$func_path; 'libs'.DIRECTORY_SEPARATOR.'functions'.DIRECTORY_SEPARATOR.'autoload'; if(!empty($auto_funcs) &&is_array($auto_funcs)) { * 是否有自己的扩展文件 * @param string $filepath路径 */ public static function my_path($filepath) { /** * pathinfo返回关联数组,根据key返回用户自定义文件位置 $path = pathinfo($filepath); /** * 形如: phpcms/modules/content/index.php * 如果存在phpcms/modules/content/MY_index.php则返回此路径 * 主要用于区别系统默认的index,添加个性化需求 */ *

if(file_exists($path['dirname'].DIRECTORY_SEPARATOR.'MY_'.$path['basename'])) { return$path['dirname'].DIRECTORY_SEPARATOR.'MY_'.$path['basename'];

} /** * 加载配置文件 * @param string $file 配置文件 * @param string $key 要获取的配置荐 * @param string $default 默认配置。当获取配置项目失败时该值发生作用。 * @paramboolean $reload 强制重新加载。 */ } else { } return false;

{

} public static function load_config($file, $key= '', $default= '', $reload= false) } /** * 如果key为空返回$file整个文件(数组形式) * 否则返回file中某一个key的值(二维数组) */ static$configs= array(); if(!$reload&&isset($configs[$file])) { } /** * 指定默认path为 CACHE_PATH/configs/+用户file */ $path = CACHE_PATH.'configs'.DIRECTORY_SEPARATOR.$file.'.php'; if(file_exists($path)) { } if(empty($key)) { } return$configs[$file]; return$configs[$file][$key]; return$default; } elseif(isset($configs[$file][$key])) { } else { $configs[$file] = include $path; if(empty($key)) { } return$configs[$file]; return$configs[$file][$key]; return$default; } elseif(isset($configs[$file][$key])) { } else { *

该base类代码较多主要定义了一些常量,写了一些加载配置、函数和类的函数,要注意的是该类中define('IN_PHPCMS', true);定义了一个进入入口的标志,用来保证访问的合法性,防止直接访问工程内的一些重要文件。另外一个要注意的是该类中的以下代码: public static function creat_app() {

} return self::load_sys_class('application');

这就是index.php中creat_app()访问的方法,该函数两次调用了pc_base类的方法,传入的application参数引入了application.class.php并返回了一个该类的实例。 该文件在phpcms/libs/classes/下,我们打开这个文件,源码如下:

<?php

/**

* application.class.php PHPCMS应用程序创建类

*

*/

classapplication {

/** * 初始化应用 */ public function __construct() { } /** * 调用事件 */ private function init() { } /** * 加载控制器-接收一个模块路径($m)和一个控制器对象($filename) * @param string $filename 控制器类 * @param string $m 模块 //加载控制器对象 $controller = $this->load_controller(); //判断该类是否存在相应事件 if(method_exists($controller, ROUTE_A)) { } /** * 检查方法权限 */ if(preg_match('/^[_]/i', ROUTE_A)) { exit('You are visiting the action is to protect the private //调用参数类 $param= pc_base::load_sys_class('param'); define('ROUTE_M', $param->route_m()); define('ROUTE_C', $param->route_c()); define('ROUTE_A', $param->route_a()); //调用应用类事件 $this->init(); action'); } else { } exit('Action does not exist.'); //调用该类的ROUTE_A方法 call_user_func(array($controller, ROUTE_A)); } else {

* @return (obj)$filename - 并引入(访问)指定控制器路径 */ private function load_controller($filename= '', $m= '') { if(empty($filename)) $filename= ROUTE_C; if(empty($m)) $m= ROUTE_M; //确定路径形如: $filepath= phpcms/modules/ROUTE_M/ROUTE_C.php

$filepath=

PC_PATH.'modules'.DIRECTORY_SEPARATOR.$m.DIRECTORY_SEPARATOR.$filename.'.php';

} } //若存在指定路径便引入用于访问 if(file_exists($filepath)) { } $classname= $filename; include$filepath; //检查该路径下是否有扩展路径,如果有则引入 if($mypath= pc_base::my_path($filepath)) { } //检查该类是否定义,如果定义,返回一个新类 if(class_exists($classname)){ } exit('Controller does not exist.'); return new $classname; exit('Controller does not exist.'); }else{ $classname= 'MY_'.$filename; include$mypath; } else {

该类就是应用创建类,前面index.php中creat_app()实际上时调用了此类,该类中首先加载了参数类param.class.php,该类定义了一些路由法则,因为PHPCMS时单入口文件,其访问方式如同/index?m=content&c=index&a=init ,该参数类主要就是定义了一些路由法则的函数,判断该访问类的哪个事件。

后面定义的常量就是调用类参数类的路由方法,$this->init()调用了自己类中的init()方法,其中又调用了load_controller(),较为详细的说明可以参考以上的注释,到此该cms就可以按照用户的路由规则进行访问,为了防止直接访问其它受保护的文件,可以在该文件前面加一句defined('IN_PHPCMS') or exit('No permission resources.');,这样就可以防止恶意的直接访问,整个系统就会按照进入base类一步一步按照路由规则进行web系统的访问。这就是所谓的单入口技术了。

此文只是简要的描述了PHPCMS中单入口的一些源码和要点,只适合读者朋友简单的参考交流,希望能多少能有所帮助。PHPCMS是国内一个优秀的开源项目,想要了解更多PHPCMS的框架信息,还需读者参考更多资料,多多学习和使用才能有更多的认识。

更多相关推荐:
spss的数据分析报告

关于某公司474名职工综合状况的统计分析报告一数据介绍本次分析的数据为某公司474名职工状况统计表其中共包含十一变量分别是id职工编号gender性别bdate出生日期edcu受教育水平程度jobcat职务等级...

spss分析报告

基于全国36个省市主要经济指标数据的spss分析一数据来源与描述1数据来源中国劳动统计年鉴20xxhttpwwwtjsjndsj20xxindexchhtm2数据描述本数据集记录了20xx年全国36个省市港澳台...

spss报告

北京理工大学珠海学院统计分析与SPSS的应用报告人均地区生产总值及人均消费水平报告学院商学院年级09级2班专业公管事业管理第3小组成员魏晗090804021048111北京理工大学珠海学院统计分析与SPSS的应...

spss数据分析报告

关于某班级20xx年度考试成绩获奖情况统计分析报告一数据介绍本次分析的数据为某班级学号排列最前的15个人在20xx年度学习获奖统计表其中共包含七个变量分别是专业学号姓名性别第一学期的成绩第二学期的成绩考级考证数...

Spss案例统计分析图书馆利用状况的调查报告

第一部分调查方案设计一调查方案1调查目的了解图书馆的利用状况为图书馆的管理和同学对图书馆的使用提供一些数据和参考意见2调查对象中国人民大学本科生3调查时间1数据取得时间六月一号晚100011002数据统计时间六...

spss对数据进行相关性分析实验报告

管理统计实验报告实验一一实验目的掌握用spss软件对数据进行相关性分析熟悉其操作过程并能分析其结果二实验原理相关性分析是考察两个变量之间线性关系的一种统计分析方法更精确地说当一个变量发生变化时另一个变量如何变化...

spss分析报告(相关性)

spss实验分析报告以下针对中国民航客运量进行数据分析一对所给数据进行分析见下表为19xx年到19xx年数据年份yx1x2x3x4x519xx231301018888149114891809219xx29833...

大学生课余生活调查报告(spss分析)

绍兴文理学院统计调查报告题目:大学生课余生活调查报告院(系):专业名称:组员:二OXX年五月大学生课余生活调查报告背景:大学是人生最美好的阶段、是过渡到成人的关键时刻、也是实现自我价值的理想场所。在这里,大学生…

spss 分析报告,课程作业

调查背景近年来随着城市的发展大量的农村人口进入城市为城市的建设作出重要的贡献但这些长期在城市的务工人员却无法得到良好的生活大量的农民进入城市在各行各业工作为城市注入了活力为社会付出了劳动力为社会创造了大量的财富...

spss的数据分析报告

关于某公司474名职工综合状况的统计分析报告一数据介绍本次分析的数据为某公司474名职工状况统计表其中共包含十一变量分别是id职工编号gender性别bdate出生日期edcu受教育水平程度jobcat职务等级...

有关工资影响的spss分析报告

应用统计学应用统计学案例分析报告薪酬与IQ教育水平的关系小组成员编写时间摘要个体收入的影响因素分析是社会学研究的经典课题个体收入不仅是经济含义的变量同时也是决定个体经济社会地位的重要指标之一所以分析员工工资的影...

spss的数据分析报告

基于SPSS的淮安地区359人旅游情况统计分析报告营销1121班一、引言:旅游统计是国家对旅游行业实施全行业研究、管理、监督、引导和控制的信息基础,是各种旅游企业、事业单位和机构从事业务管理和决策的信息依据。改…

spss分析报告(15篇)