第一部分:简单概念
CMS(内容管理系统)
- 内容管理系统(CMS)管理数字内容的创建和修改,通常支持多个用户协作管理。
- 实现基于WEB的内容编辑、发布、展示、检索。
- 管理的内容包括文本和嵌入图形,照片,视频,音频,地图等元素。
- 大多数的CMS会主要解决两部分功能:前台模板的管理,后台数据的管理。
PHPCMS DEDECMS
WUZHICMS
- PHP开发
- 开源
MVC
MVC模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。
- 控制器(Controller)- 负责转发请求,对请求进行处理(页面的路由)。
- 视图(View) - 界面设计人员进行图形界面设计。
-
模型(Model) - 程序员编写程序应有的功能(实现算法等等)、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。
v2-30f72a70d6d84065d2147754bf2ad59f_1200x500.jpg
目的
- 可扩展性
- 可复用性
- 可维护性
- 灵活性加强
第二部分:五指CMS的结构
-
专业版本结构:
TIM图片20180205230216.png -
默认版本结构:
-
运行机制
- 入口文件 index.php
<?php
/**
* 程序入口文件
*/
//检测PHP环境
if(PHP_VERSION < '5.2.0') die('Require PHP > 5.2.0 ');
//定义当前的网站物理路径
define('WWW_ROOT',dirname(__FILE__).'/');
require './configs/web_config.php';
require COREFRAME_ROOT.'core.php';
$app = load_class('application');
$app->run();
?>
- 配置文件 web_config.php
<?php
defined('WWW_ROOT') or exit('No direct script access allowed');
define('COREFRAME_ROOT',substr(dirname(__FILE__),0,-7).'coreframe'.DIRECTORY_SEPARATOR);
define('CACHE_ROOT',substr(dirname(__FILE__),0,-7).'caches'.DIRECTORY_SEPARATOR);
define('CACHE_EXT','OQ52M');
//勿忘-网站上线后,需要修改下面 3项
define('OPEN_DEBUG',0);//开启调试模式?2 服务器上开发调试 ;1 本地开发调试,遇到错误终止;0 关闭-网站上线后,需要关闭该项
define('AUTO_CACHE_TPL',1);//是否自动缓存模版,网站上线后,必须关闭该项
define('ERROR_REPORT',1);//错误信息现实级别:1 ,显示高级别错误,0 关闭错误提醒(上线后,使用该项) 2 显示所有错误(开发模式)
//define('TEST_CHECKCODE',1);//1 打开测试验证码,0 正常验证码
//define('SQL_LOG',1);//记录操作SQL
define('WWW_PATH','/');//网站安装路径,二级目录形式为:/mydemo/
define('WEBURL','http://www.zgw.com/');//网站域名
//Cookie配置
define('COOKIE_DOMAIN','');//Cookie 作用域
define('COOKIE_PATH','/');//Cookie 作用路径
define('COOKIE_PRE','XEt_'); //Cookie 前缀
define('COOKIE_TTL',0); //Cookie 生命周期,0 表示随浏览器进程
//附件相关配置
define('ATTACHMENT_ROOT',WWW_ROOT.'uploadfile/');
define('ATTACHMENT_URL','http://www.zgw.com/uploadfile/');//附件路径
define('R','http://www.zgw.com/res/');//静态文件存储目录
define('_KEY','MZymUMYv'); //密钥,最长8位
define('LANG','zh-cn'); //网站默认语言包
define('FOUNDERS','1'); //网站创始人ID,多个ID逗号分隔
define('TIME_ZONE','Etc/GMT-8');
define('CHARSET','utf-8');
define('POSTFIX','.html');//.html/.htm/.shtml
define('CLOSE',0);//关闭网站前台所有动态PHP功能,包括API
define('_SU','wuzhicms');
//开启移动页面自动识别
define('SUPPORT_MOBILE',0);//0,不支持移动页面,1,自动识别,动态,伪静态下可用,静态页面通过js判断跳转到动态地址完成识别
//默认模版配置
define('TPLID','p1');
//开启站群
define('ENABLE_SITES',0);
define('TEST_CHECKCODE',1);//1 打开测试验证码,0 正常验证码
define('SQL_LOG',0);
//强制刷新css,js缓存
define('VN', uniqid());//正常情况为 define('VN', 1);
- core.php
<?php
defined('WWW_ROOT') or exit('No direct script access allowed');
/**
* 核心文件
*/
define('VERSION','4.0.0');
$GLOBALS = array();
define('SYSTEM_NAME','wuzhicms');
define('IN_WZ',true);
if(ERROR_REPORT==1) {
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT);
} elseif(ERROR_REPORT==0) {
error_reporting(0);
} else {
error_reporting(E_ALL);
}
ini_set('display_errors', 1);
set_exception_handler('log_exception');
//开始运行时间
$GLOBALS['_startTime'] = microtime(true);
if(version_compare(PHP_VERSION,'5.4.0','<')) {
ini_set('magic_quotes_runtime',0);
define('MAGIC_QUOTES_GPC',get_magic_quotes_gpc() ? 1 : 0);
} else {
define('MAGIC_QUOTES_GPC', 0);
}
define('IS_WIN',strstr(PHP_OS, 'WIN') ? 1 : 0);
define('IS_CLI',PHP_SAPI=='cli'? 1 : 0);
define('SYS_TIME', time());
define('HTTP_REFERER', isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '');
//设置本地时差
date_default_timezone_set(TIME_ZONE);
//输出页面字符集
header('Content-type: text/html; charset='.CHARSET);
//if(extension_loaded("zlib") && !ob_start("ob_gzhandler")) ob_start();
//将GET,POST 参数全部转给 GLOBALS ,然后注销 get/post
set_globals();
load_function('common');
autoload();
$_POST['SUPPORT_MOBILE'] = SUPPORT_MOBILE;
/**
* 加载类函数
* @param string $class 类名称
* @param string $m 模块英文名
* @param string $param 初始化参数
* @return class
*/
function load_class($class, $m = 'core', $param = NULL) {
static $static_class = array();
//判断是否存在类,存在则直接返回
if (isset($static_class[$class])) {
return $static_class[$class];
}
$name = FALSE;
if (file_exists(COREFRAME_ROOT.'app/'.$m.'/libs/class/'.$class.'.class.php')) {
$name = 'WUZHI_'.$class;
if (class_exists($name, FALSE) === FALSE) {
require_once(COREFRAME_ROOT.'app/'.$m.'/libs/class/'.$class.'.class.php');
}
}
//如果存在扩展类,则初始化扩展类
if ($class!='application' && $class!='admin' && file_exists(COREFRAME_ROOT.'app/'.$m.'/libs/class/EXT_'.$class.'.class.php')) {
$name = 'EXT_'.$class;
if (class_exists($name, FALSE) === FALSE) {
require_once(COREFRAME_ROOT.'app/'.$m.'/libs/class/EXT_'.$class.'.class.php');
}
}
if ($name === FALSE) {
$full_dir = '';
if(OPEN_DEBUG) $full_dir = COREFRAME_ROOT.'app/'.$m.'/libs/class/';
echo 'Unable to locate the specified class: '.$full_dir.$class.'.class.php';
exit();
}
$static_class[$class] = isset($param) ? new $name($param) : new $name();
return $static_class[$class];
}
/**
* 加载类函数
* @param string $filename 名称
* @param string $m 模块英文名
*/
function load_function($filename, $m = 'core') {
static $static_func = array();
//判断是否加载过,存在则直接返回
if (isset($static_func[$filename])) {
return true;
}
require_once(COREFRAME_ROOT.'app/'.$m.'/libs/function/'.$filename.'.func.php');
}
/**
* 加载类函数
* @param string $filename 文件名称
* @param string $param 参数名称
* @return array|string
*/
function get_config($filename,$param = '') {
static $config;
if(isset($config[$filename])) return $param ? $config[$filename][$param] : $config[$filename];
if(file_exists(WWW_ROOT.'configs/'.$filename.'.php')) {
$config[$filename] = include WWW_ROOT.'configs/'.$filename.'.php';
} else {
$full_dir = '';
if(OPEN_DEBUG) $full_dir = WWW_ROOT.'configs/';
echo 'Unable to locate the specified config: '.$full_dir.$filename.'.php';
exit();
}
return $param ? $config[$filename][$param] : $config[$filename];
}
function autoload() {
$path = COREFRAME_ROOT.'extend/function/*.func.php';
$auto_funcs = glob($path);
if(!empty($auto_funcs) && is_array($auto_funcs)) {
foreach($auto_funcs as $func_path) {
include $func_path;
}
}
}
/**
* 检查GLOBALS中是否存在变量
* @param $key
* @param int $check_sql 是否sql_replace过滤
* @return mixed|string
*/
function input($key,$check_sql = 1) {
if(isset($GLOBALS[$key])) {
return $check_sql ? sql_replace($GLOBALS[$key]) : $GLOBALS[$key];
} else {
return '';
}
}
function set_globals() {
if(isset($_GET)) {
foreach ($_GET as $_key => $_value) {
$GLOBALS[$_key] = gpc_stripslashes($_value);
}
$_GET = array();
}
if(isset($_POST)) {
foreach ($_POST as $_key => $_value) {
$GLOBALS[$_key] = gpc_stripslashes($_value);
}
$_POST = array();
}
if(isset($GLOBALS['page'])) {
$GLOBALS['page'] = max(intval($GLOBALS['page']),1);
$GLOBALS['page'] = min($GLOBALS['page'],100000000);
} else {
$GLOBALS['page'] = 0;
}
$_COOKIE = gpc_stripslashes($_COOKIE);
$GLOBALS['_groupid'] = get_cookie('_groupid');
if(!$GLOBALS['_groupid']) {
$GLOBALS['_groupid'] = 4;
}
}
function p_addslashes($string) {
if(is_array($string)) {
$keys = array_keys($string);
foreach($keys as $key) {
$val = $string[$key];
unset($string[$key]);
$string[addslashes($key)] = p_addslashes($val);
}
} else {
$string = addslashes($string);
}
return $string;
}
function p_stripslashes($string) {
if ( ! is_array($string)){
return stripslashes($string);
}
return array_map('p_stripslashes', $string);
}
function gpc_stripslashes($data) {
if(MAGIC_QUOTES_GPC) {
return p_stripslashes($data);
} else {
return $data;
}
}
/**
* 设置 cookie
* @param string $string 变量名
* @param string $value 变量值
* @param int $time 过期时间
* @param bool $encrypt = true 是否加密存储
*/
function set_cookie($string, $value = '', $time = 0, $encrypt = true) {
$time = $time > 0 ? $time : ($value == '' ? SYS_TIME - 3600 : 0);
$s = $_SERVER['SERVER_PORT'] == '443' ? 1 : 0;
$string = COOKIE_PRE.$string;
if($encrypt) $value = encode($value);
setcookie($string, $value, $time, COOKIE_PATH, COOKIE_DOMAIN, $s);
}
/**
* 获取通过 set_cookie 设置的 cookie 变量
* @param string $string 变量名
* @param string $default 默认值
* @return mixed 成功则返回cookie 值,否则返回 false
*/
function get_cookie($string, $default = '', $encrypt = true) {
$string = COOKIE_PRE.$string;
return isset($_COOKIE[$string]) ? decode($_COOKIE[$string]) : $default;
}
/**
*
* @param string $string 变量名
* @return array
*/
function p_unserialize($string) {
if(($ret = unserialize($string)) === false) {
$ret = unserialize(stripslashes($string));
}
return $ret;
}
/**
* 加密字符串
*
* @param $string
* @param string $key
*/
function encode($string,$key = '') {
$encode = load_class('encrypt');
return $encode->encode($string,$key);
}
/**
* 解密字符串
*
* @param $string
* @param string $key
*/
function decode($string,$key = '') {
$encode = load_class('encrypt');
return $encode->decode($string,$key);
}
/**
* Error handler, passes flow over the exception logger with new ErrorException.
*/
function log_error( $num, $str, $file, $line, $context = null ) {
if(ERROR_REPORT<2 && $num==8) return '';
log_exception( new ErrorException( $str, 0, $num, $file, $line ));
}
/**
* Uncaught exception handler.
*/
function log_exception($e) {
$file = str_replace(rtrim(COREFRAME_ROOT,'/'),'coreframe->',$e->getFile());
$file = str_replace(rtrim(WWW_ROOT,'/'),'www->',$file);
$file = str_replace(rtrim(CACHE_ROOT,'/'),'caches->',$file);
$data = array();
$data['type'] = get_class($e);
$data['msg'] = $e->getMessage();
$data['file'] = $file;
$data['line'] = $e->getLine();
$data['version'] = VERSION;
$data['php_version'] = PHP_VERSION;
$data['referer'] = URL();
if (ERROR_REPORT) {
if(IS_CLI==0 && !defined('CLI_DISPLAY')) {
print "<!DOCTYPE html><div style='text-align: center;'>";
print "<h5 style='color: rgb(190, 50, 50);'>WuzhiCMS Exception Occured:</h5>";
print "<table style='width: 800px; display: inline-block;'>";
print "<tr style='background-color:rgb(230,230,230);text-align:left;'><th style='width: 80px;'>Type</th><td>" . $data['type'] . "</td></tr>";
print "<tr style='background-color:rgb(240,240,240);text-align:left;'><th>Message</th><td>{$data['msg']}</td></tr>";
print "<tr style='background-color:rgb(230,230,230);text-align:left;'><th>File</th><td>{$file}</td></tr>";
print "<tr style='background-color:rgb(240,240,240);text-align:left;'><th>Line</th><td>{$data['line']}</td></tr>";
print "<tr style='background-color:rgb(230,230,230);'><th colspan='2'><a href='http://www.wuzhicms.com/index.php?m=help&f=logerror&msg={$data['msg']}&file={$data['file']}&line={$data['line']}' target='_blank'>Need Help?</a></th></tr>";
print "</table></div>";
} else {
print "------------- WuzhiCMS Exception Occured:------------- \r\n";
print "Type: {$data['type']} \r\n";
print "Message: {$data['msg']} \r\n";
print "File: {$data['file']} \r\n";
print "Line: {$data['line']} \r\n";
print date('Y-m-d H:i:s')."\r\n";
}
if(OPEN_DEBUG) exit();
} else {
$message = "Time: " . date('Y-m-d H:i:s') . "; Type: " . $data['type'] . "; Message: {$e->getMessage()}; File: {$data['file']}; Line: {$data['line']};";
@file_put_contents(CACHE_ROOT. "logs/error-".CACHE_EXT.'-'.date("ym").".log", $message . PHP_EOL, FILE_APPEND );
}
}
- application.class.php (Controller)
<?php
defined('IN_WZ') or exit('No direct script access allowed');
/**
* M/F/V 路由
*/
final class WUZHI_application {
/**
* @var app,模块名,取值方式:M
*/
private $_m;
/**
* @var 文件名 取值方式:F
*/
private $_f;
/**
* @var 方法名 取值方式:V
*/
private $_v;
/**
* Class constructor
*/
public function __construct() {
self::setconfig();
define('M',$this->_m);
define('F',$this->_f);
define('V',$this->_v);
}
/**
* 设置路由
*/
/**
* 设置路由
*/
private function setconfig() {
$sn = $_SERVER["SERVER_NAME"];
$route_config = get_config('route_config');
if(isset($route_config[$sn])) {
$route_config = $route_config[$sn];
} else {
$route_config = $route_config['default'];
}
$this->_m = isset($GLOBALS['m']) ? sql_replace($GLOBALS['m']) : $route_config['m'];
$this->_f = isset($GLOBALS['f']) ? sql_replace($GLOBALS['f']) : $route_config['f'];
$this->_v = isset($GLOBALS['v']) ? sql_replace($GLOBALS['v']) : $route_config['v'];
$this->_v = strip_tags($this->_v);
if(isset($route_config['_get'])) {
foreach($route_config['_get'] as $key=>$value) {
$_GET[$key] = $value;
}
}
}
/**
* 运行
*/
public function run() {
$file = $this->load_file();
if(!defined('IN_ADMIN')) {
if(CLOSE) {
$siteconfigs = get_cache('siteconfigs');
MSG($siteconfigs['close_reason']);
}
}
if (method_exists($file, V)) {
if (preg_match('/^[_]/i', V)) {
exit('You are visiting the action is to protect the private action');
} else {
call_user_func(array($file, V));
}
} elseif(class_exists($GLOBALS['_CLASS_NAME_'],FALSE)) {
exit('Action:'.V.' not exists.');
}
}
/**
* 加载文件
* @param string $filename 文件名
* @param string $app 所属模块
* @param string $param 初始化参数
* @return bool
*/
public static function load_file($filename = '', $app = '', $param = '') {
static $static_file = array();
if(isset($GLOBALS['_su']) && $GLOBALS['_su']== _SU) {
$_admin_dir = '/admin';
} else {
$_admin_dir = '';
}
//判断是否存在类,存在则直接返回
if (isset($static_file[$filename])) {
return $static_file[$filename];
}
if (empty($filename)) $filename = F;
if (empty($app)) $app = M;
$filepath = COREFRAME_ROOT.'app/'.$app.$_admin_dir.'/'.$filename.'.php';
$name = FALSE;
if (file_exists($filepath)) {
//$name = 'WUZHI_'.$filename;
$name = $filename;
if (class_exists($name, FALSE) === FALSE) {
require_once($filepath);
}
}
//如果存在扩展类,则初始化扩展类
if (file_exists(COREFRAME_ROOT.'app/'.$app.$_admin_dir.'/EXT_'.$filename.'.php')) {
$name = 'EXT_'.$filename;
if (class_exists($name, FALSE) === FALSE) {
require_once(COREFRAME_ROOT.'app/'.$app.$_admin_dir.'/EXT_'.$filename.'.php');
}
}
$GLOBALS['_CLASS_NAME_'] = '';
if ($name === FALSE) {
$full_dir = '';
if(OPEN_DEBUG) {
$full_dir = COREFRAME_ROOT.'app/'.$app.$_admin_dir.'/';
} else {
$full_dir = '/coreframe/app/'.$app.$_admin_dir.'/';
}
$filename = strip_tags($filename);
echo 'Unable to locate the specified filename: '.$full_dir.$filename.'.php';
exit();
}
if (class_exists($name, FALSE) === FALSE) {
return TRUE;
}
$GLOBALS['_CLASS_NAME_'] = $name;
$static_file[$filename] = isset($param) ? new $name($param) : new $name();
return $static_file[$filename];
}
}
-
app/* (Module)
TIM图片20180205233515.png
image.png
附:index.php
<?php
class index{
private $siteconfigs;
public function __construct() {
$this->db = load_class('db');
$this->siteid = $_GET['siteid'] ? $_GET['siteid'] : 1;
$this->siteconfigs = get_cache('siteconfigs_'.$this->siteid);
}
/**
* 网站首页
*/
public function init() {
$isindex = 1;
$siteconfigs = $this->siteconfigs;
$seo_title = $siteconfigs['sitename'];
$seo_keywords = $siteconfigs['seo_keywords'];
$seo_description = $siteconfigs['seo_description'];
$categorys = get_cache('category','content');
$_uid = get_cookie('_uid');
if(ENABLE_SITES) {
$siteid = intval($_GET['siteid']);
if(!$siteid) $siteid = 1;
$tplid = TPLID.'-'.$siteid;
} else {
$tplid = TPLID;
}
$language_set = 1;
include T('content','index',$tplid);
}
}
-
页面模板(View)
image.png
第三部分:常见常用的函数、方法
- 全局函数
/**
* 加载类函数
* @param string $class 类名称
* @param string $m 模块英文名
* @param string $param 初始化参数
* @return class
*/
function load_class($class, $m = 'core', $param = NULL) {
...
}
/**
* 加载类函数
* @param string $filename 名称
* @param string $m 模块英文名
*/
function load_function($filename, $m = 'core') {
...
}
/**
* 加载类函数
* @param string $filename 文件名称
* @param string $param 参数名称
* @return array|string
*/
function get_config($filename,$param = '') {
...
}
/**
* 设置 cookie
* @param string $string 变量名
* @param string $value 变量值
* @param int $time 过期时间
* @param bool $encrypt = true 是否加密存储
*/
function set_cookie($string, $value = '', $time = 0, $encrypt = true) {
...
}
/**
* 获取通过 set_cookie 设置的 cookie 变量
* @param string $string 变量名
* @param string $default 默认值
* @return mixed 成功则返回cookie 值,否则返回 false
*/
function get_cookie($string, $default = '', $encrypt = true) {
...
}
...
core/libs/funtion/common.func.php
- 数据库操作方法
/**
* 查询多条数据
* @param $table 数据表名
* @param array|string $where 条件 ,数组或者字符串 .如:array('id'=>1,'cid'=>1) 或 `id`=1 AND `cid`=1
* @param string $field 要查询的字段
* @param int $startid 开始索引,如果是从第二条开始,那么则为1,mysql从0开始索引
* @param int $pagesize 每页显示数量,如果不分页,则显示为总数
* @param int $page 当前页
* @param string $order 排序
* @param string $group mysql group by 属性
* @param string $keyfield 以某字段名为结果索引
* @param string $urlrule url规则
* @param array $array url规则中的参数名和参数值,二维数组
* @param int $colspan 分页显示总列数
* @return array
*/
final public function get_list($table, $where = '', $field = '*', $startid = 0, $pagesize = 200, $page = 0, $order = '', $group = '', $keyfield = '', $urlrule = '',$array = array(),$colspan = 10) {
..
}
/**
* 获取单条记录查询
* @param $table 表名称
* @param $where 查询条件
* @param $field 需要查询的字段[多个字段用逗号隔开:例如,field1,field2]
* @param $startid 开始的条数,limit $startid,10
* @param $order 排序方式 [默认按数据库默认方式排序]
* @param $group 分组方式 [默认为空]
* @return array/null 数据查询结果集,如果不存在,则返回空
*/
final public function get_one($table, $where = '', $field = '*', $startid = 0, $order = '', $group = '') {
...
}
/**
* 执行添加记录操作
* @param $data 要增加的数据,参数为数组。数组key为字段值,数组值为数据取值
* @param $returnid 是否返回新建ID号
* @param $replace_into 是否采用 replace into的方式添加数据
* @return boolean
*/
final public function insert($table, $data, $returnid = TRUE, $replace_into = FALSE) {
...
}
/**
* 执行更新记录操作
* @param $data 要更新的数据内容,参数可以为数组也可以为字符串,建议数组。
* 为数组时数组key为字段值,数组值为数据取值
* @param $where 更新数据时的条件,可为数组或字符串
* @return boolean
*/
final public function update($table, $data, $where = '') {
...
}
/**
* 执行删除记录操作
* @param $where 删除数据条件,不充许为空。
* @return boolean
*/
final public function delete($table, $where = '') {
...
}
网友评论