PHPCMS是采用MVC设计模式开发,基于模块和操作的方式进行访问,采用单一入口模式进行项目部署和访问,无论访问任何一个模块或者功能,只有一个统一的入口。

  入口程序是在前期处理用户请求的引导程序。它是唯一一个可以被最终用户直接请求运行的。

  PHPCMS V9的入口程序(index.php)如下:

 <?php
/**
* index.php PHPCMS 入口
*
* @copyright (C) 2005-2010 PHPCMS
* @license http://www.phpcms.cn/license/
* @lastmodify 2010-6-1
*/
//PHPCMS根目录 define('PHPCMS_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR); include PHPCMS_PATH.'/phpcms/base.php'; pc_base::creat_app(); ?>

  第一行:定义项目的根路径,后面文件查找依赖此变量。

  DIRECTORY_SEPARATOR(目录分隔符)是一个返回与操作系统相关的路径分隔符的内置命令,不需要任何定义与包含即可直接使用。由于windows上习惯性的使用\作为文件分隔符,但是在linux上人家是不认识这个标识的,人家只认识/,于是就要引入下面这个php内置常量:DIRECTORY_SEPARATOR。

  第二行:根据项目根路径引入base.php文件,文件内容如下:

 <?php
/**
* base.php PHPCMS框架入口文件
*
* @copyright (C) 2005-2010 PHPCMS
* @license http://www.phpcms.cn/license/
* @lastmodify 2010-6-7
*/ /*
* 定义常量IN_PHPCMS
*/
// 定义常量IN_PHPCMS
define('IN_PHPCMS', true); /*
* 定义PHPCMS框架路径、缓存文件夹地址
*/
//PHPCMS框架路径
define('PC_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR);
if(!defined('PHPCMS_PATH')) define('PHPCMS_PATH', PC_PATH.'..'.DIRECTORY_SEPARATOR); //缓存文件夹地址
define('CACHE_PATH', PHPCMS_PATH.'caches'.DIRECTORY_SEPARATOR); /*
* 主机协议、当前访问的主机名、来源、系统开始时间
*/
//主机协议
define('SITE_PROTOCOL', isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://'); //当前访问的主机名
define('SITE_URL', (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '')); //来源
define('HTTP_REFERER', isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''); //系统开始时间
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); 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'))
{
ob_start('ob_gzhandler');
}
else
{
ob_start();
} class pc_base
{
/**
* 初始化应用程序
*/
public static function creat_app()
{
return self::load_sys_class('application');
}
/**
* 加载系统类方法
* @param string $classname 类名
* @param string $path 扩展地址
* @param intger $initialize 是否初始化
*/
public static function load_sys_class($classname, $path = '', $initialize = 1)
{
return self::_load_class($classname, $path, $initialize);
} /**
* 加载应用类方法
* @param string $classname 类名
* @param string $m 模块
* @param intger $initialize 是否初始化
*/
public static function load_app_class($classname, $m = '', $initialize = 1)
{
$m = empty($m) && defined('ROUTE_M') ? ROUTE_M : $m;
if (empty($m))
return false;
return self::_load_class($classname, 'modules'.DIRECTORY_SEPARATOR.$m.DIRECTORY_SEPARATOR.'classes', $initialize);
} /**
* 加载数据模型
* @param string $classname 类名
*/
public static function load_model($classname)
{
return self::_load_class($classname,'model');
} /**
* 加载类文件函数
* @param string $classname 类名
* @param string $path 扩展地址
* @param intger $initialize 是否初始化
*/
private static function _load_class($classname, $path = '', $initialize = 1)
{
static $classes = array();
if (empty($path))
$path = 'libs'.DIRECTORY_SEPARATOR.'classes'; $key = md5($path.$classname);
if (isset($classes[$key]))
{
if (!empty($classes[$key]))
{
return $classes[$key];
}
else
{
return true;
}
}
if (file_exists(PC_PATH.$path.DIRECTORY_SEPARATOR.$classname.'.class.php'))
{
include PC_PATH.$path.DIRECTORY_SEPARATOR.$classname.'.class.php';
$name = $classname;
if ($my_path = self::my_path(PC_PATH.$path.DIRECTORY_SEPARATOR.$classname.'.class.php'))
{
include $my_path;
$name = 'MY_'.$classname;
}
if ($initialize)
{
$classes[$key] = new $name;
}
else
{
$classes[$key] = true;
} return $classes[$key];
}
else
{
return false;
}
} /**
* 加载系统的函数库
* @param string $func 函数库名
*/
public static function load_sys_func($func)
{
return self::_load_func($func);
} /**
* 自动加载autoload目录下函数库
* @param string $func 函数库名
*/
public static function auto_load_func($path='')
{
return self::_auto_load_func($path);
} /**
* 加载应用函数库
* @param string $func 函数库名
* @param string $m 模型名
*/
public static function load_app_func($func, $m = '')
{
$m = empty($m) && defined('ROUTE_M') ? ROUTE_M : $m;
if (empty($m))
return false;
return self::_load_func($func, 'modules'.DIRECTORY_SEPARATOR.$m.DIRECTORY_SEPARATOR.'functions');
} /**
* 加载插件类库
*/
public static function load_plugin_class($classname, $identification = '' ,$initialize = 1)
{
$identification = empty($identification) && defined('PLUGIN_ID') ? PLUGIN_ID : $identification;
if (empty($identification))
return false;
return pc_base::load_sys_class($classname, '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') ? PLUGIN_ID : $identification;
if (empty($identification))
return false;
$path = 'plugin'.DIRECTORY_SEPARATOR.$identification.DIRECTORY_SEPARATOR.'functions'.DIRECTORY_SEPARATOR.$func.'.func.php';
$key = md5($path);
if (isset($funcs[$key]))
return true;
if (file_exists(PC_PATH.$path))
{
include PC_PATH.$path;
}
else
{
$funcs[$key] = false;
return false;
}
$funcs[$key] = true;
return true;
} /**
* 加载插件数据模型
* @param string $classname 类名
*/
public static function load_plugin_model($classname, $identification)
{
$identification = empty($identification) && defined('PLUGIN_ID') ? PLUGIN_ID : $identification;
$path = 'plugin'.DIRECTORY_SEPARATOR.$identification.DIRECTORY_SEPARATOR.'model';
return self::_load_class($classname,$path);
} /**
* 加载函数库
* @param string $func 函数库名
* @param string $path 地址
*/
private static function _load_func($func, $path = '')
{
static $funcs = array();
if (empty($path)) $path = 'libs'.DIRECTORY_SEPARATOR.'functions';
$path .= DIRECTORY_SEPARATOR.$func.'.func.php';
$key = md5($path);
if (isset($funcs[$key]))
return true;
if (file_exists(PC_PATH.$path))
{
include PC_PATH.$path;
}
else
{
$funcs[$key] = false;
return false;
}
$funcs[$key] = true;
return true;
} /**
* 加载函数库
* @param string $func 函数库名
* @param string $path 地址
*/
private static function _auto_load_func($path = '')
{
if (empty($path)) $path = 'libs'.DIRECTORY_SEPARATOR.'functions'.DIRECTORY_SEPARATOR.'autoload';
$path .= DIRECTORY_SEPARATOR.'*.func.php';
$auto_funcs = glob(PC_PATH.DIRECTORY_SEPARATOR.$path);
if(!empty($auto_funcs) && is_array($auto_funcs))
{
foreach($auto_funcs as $func_path)
{
include $func_path;
}
}
}
/**
* 是否有自己的扩展文件
* @param string $filepath 路径
*/
public static function my_path($filepath)
{
$path = pathinfo($filepath);
if (file_exists($path['dirname'].DIRECTORY_SEPARATOR.'MY_'.$path['basename']))
{
return $path['dirname'].DIRECTORY_SEPARATOR.'MY_'.$path['basename'];
}
else
{
return false;
}
} /**
* 加载配置文件
* @param string $file 配置文件
* @param string $key 要获取的配置键
* @param string $default 默认配置。当获取配置项目失败时该值发生作用。
* @param boolean $reload 强制重新加载。
*/
public static function load_config($file, $key = '', $default = '', $reload = false)
{
static $configs = array();
if (!$reload && isset($configs[$file]))
{
if (empty($key))
{
return $configs[$file];
}
elseif (isset($configs[$file][$key]))
{
return $configs[$file][$key];
}
else
{
return $default;
}
}
$path = CACHE_PATH.'configs'.DIRECTORY_SEPARATOR.$file.'.php';
if (file_exists($path))
{
$configs[$file] = include $path;
}
if (empty($key))
{
return $configs[$file];
}
else if (isset($configs[$file][$key]))
{
return $configs[$file][$key];
}
else
{
return $default;
}
}
}

  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] 加载共用函数库

 //加载公用函数库
pc_base::load_sys_func('global');
pc_base::load_sys_func('extention');
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.

顺序 选择 循环 总结

PHPCMS V9 框架代码分析(入口程序)的更多相关文章

  1. phpcms v9框架的目录结构分析

    phpcms v9框架的目录结构分析:      了解v9框架的目录结构,有助于帮助我们快速建立起对v9框架的一个整体认识 打开"mycms"项目,有如下文件和目录      使用 ...

  2. phpcms V9 框架目录结构

    phpcms v9框架的目录结构分析:      了解v9框架的目录结构,有助于帮助我们快速建立起对v9框架的一个整体认识 打开"mycms"项目,有如下文件和目录      使用 ...

  3. Android4.0图库Gallery2代码分析(一) 程序整体结构

    Android4.0图库Gallery2代码分析(一) 程序整体结构 Gallery2的用例图分析:Gallery2主要功能是实现本地存储器.MTP存储器和网络存储器中媒体(图像和视频)的浏览.显示和 ...

  4. 一个简单的"RPC框架"代码分析

    0,服务接口定义---Echo.java /* * 定义了服务器提供的服务类型 */ public interface Echo { public String echo(String string) ...

  5. C#代码分析--阅读程序,回答问题

    阅读下面程序,请回答如下问题: 问题1:这个程序要找的是符合什么条件的数? 问题2:这样的数存在么?符合这一条件的最小的数是什么? 问题3:在电脑上运行这一程序,你估计多长时间才能输出第一个结果?时间 ...

  6. Linux摄像头驱动学习之:(六)UVC-基本框架代码分析

    仿照内核的自带UVC(usb video class)驱动程序写的一版简化驱动,仅供学习,实际项目开发中应该尽量使用内核自带的驱动,除非内核自带的驱动不支持此款硬件才需要自己写驱动. 下面就直接上代码 ...

  7. lor框架代码分析

    属性 lor: version router route request response fn app create_app Router Route Request Response 属性 lor ...

  8. PHPCMS V9 学习总结

    在实现PHPCMS网站过程中,根据业务需求,我们遇到很多问题,特此总结如下,以便大家参考学习. [1]PHPCMS V9系统目录简析 在研究所有问题之前,请先了解一下系统的文件目录结构,具体如下图所示 ...

  9. PHPCMS V9 学习总结(转)

    转自:http://www.cnblogs.com/Braveliu/p/5074930.html 在实现PHPCMS网站过程中,根据业务需求,我们遇到很多问题,特此总结如下,以便大家参考学习. [1 ...

随机推荐

  1. Android基于XMPP的即时通讯3-表情发送

    这篇博文主要讲表情发送的一些东西. 参考:Android基于XMPP的即时通讯1-基本对话 1.准备好资源文件 采用的是emoji的表情,我打包好了,下载地址:http://files.cnblogs ...

  2. 把应用程序exe 注册成为windows 服务的方法

    由于在Windows 服务器上必须要启动一个软件,提供外网访问内网的客户端软件,但是由于每次远程服务器之后会注销当前用户,所以客户端软件就会自动退出,那么我在外网的系统就不能支持访问了. 解决方案:将 ...

  3. redis集群搭建

    1.  Redis Cluster的架构图.            (1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽. (2)节点的fail是通过集群 ...

  4. MySQL执行存储过程权限

    http://url.cn/f2bj78 MySQL grant不能在on后面写多个对象

  5. myeclipse + tomcat 项目自动部署

    在MyEclipse中设置项目的自动部署需要综合考虑两个方面: 1是MyEclipse本身,通过主菜单中project->auto ,另一个就是tomcat配置文件.配置文件包括 conf 下的 ...

  6. BizTalk开发系列(一) "Hello World"

    学习开发语言的时候很喜欢输出“Hello World”作为第一个程序.今天我们也在BizTalk 上创建一个简单的 "Hello World" 程序. BizTalk的时候有很多文 ...

  7. 让你的网站秒开 为IIS启用“内容过期”

    让你的网站秒开,为IIS启用“内容过期” 什么是内容过期? 当用户第一次访问你的网站,浏览器从你的网站主机下载内容,如果用户第二次访问你的网站,浏览器从缓存读取内容.你知道浏览器从缓存读取网页有多快吗 ...

  8. profile

    项目开发中,使用git最为版本控制工具,往往会建立开发分支.测试分支和生产分支. 各个分支的数据库url,所依赖的接口url可能不同,直接配置的话,在合并分支时往往出现冲突.使用profile可以有效 ...

  9. [daily][device] linux添加打印机

    只用过HP的打印机,用过两个,分别是:HP_p2055dn, 和 HP_LaserJet_Professional_M1216nfh  别的不知道.以下内容仅试用于HP打印机. 第一:装HP,打印机工 ...

  10. 【C++】类型转换(学习笔记)

    1. 隐式类型转换,相关联的类型(e.g.int vs double)之间可以发生隐式类型转换. 比如,在条件中,非布尔类型转为布尔类型: 初始化时,初始值变为变量类型: 赋值时,右值变成左侧的类型: ...