<?php
/**************************************************
* Created: 2010-06-08
*
* 框架核心文件
*
* @Xweibo (C)1996-2099 SINA Inc.
* @Author xionghui <xionghui1@staff.sina.com.cn>
*
***************************************************/
class APP
{
//------------------------------------------------------------------
function APP(){
}
//------------------------------------------------------------------
/**
* 初始化 APP
* @return 无返回值
*/
function init(){
static $is_init;
if ($is_init) {return true;}
APP::_initConfig();
APP::_initRouteVar();
APP::_aclCheck();
APP::_doPreActions();
$is_init = true;
}
//------------------------------------------------------------------
/// 访问控制检查
function _aclCheck(){
$entry = V('-:aclTable/E');
// 入口控制配置不为空
if ( is_array($entry) && !empty($entry) ){
foreach($entry as $e){
}
}
$ips = V('-:aclTable/IP');
// IP控制配置不为空
if ( is_array($ips) && !empty($ips) ){
foreach($ips as $ip){
}
}
}
//------------------------------------------------------------------
/// 解释路由模式为 rewrite 时的 GET 变量
function _initRouteVar(){
if ( !in_array(R_MODE,array(2,3))) {return true;}
$ss = trim(V('S:PATH_INFO',''),'/');
if (empty($ss)) {return true;}
if (preg_match_all("#/([a-z0-9_]+)-([^/]+)#sim",$ss,$pv)){
foreach ($pv[1] as $i=>$ni){
// echo " $ni => ".($pv[2][$i])."\n"; //urldecode
$_GET[$ni] = urldecode($pv[2][$i]);
$_REQUEST[$ni] = urldecode($pv[2][$i]);
V('g:'.$ni, $_GET[$ni], true);
V('r:'.$ni, $_GET[$ni], true);
}
}
}
//------------------------------------------------------------------
/**
* 初始化配置
* @return 无返回值
*/
function _initConfig(){
if (!is_array($GLOBALS[V_GLOBAL_NAME])){
$GLOBALS[V_GLOBAL_NAME] = array();
}
if (APP::V('g:'.V_AJAX_FLAG_NAME, false)){
define('IS_IN_AJAX', true);
}else{
define('IS_IN_AJAX', false);
}
// 兼容 WIN 服务器中的 \ 路径问题
if (PHP_OS=='WINNT'){
$v1 = str_replace('\\','/',V('S:DOCUMENT_ROOT'));
$v2 = str_replace('\\','/',V('S:SCRIPT_FILENAME'));
V('S:DOCUMENT_ROOT',$v1,true);
V('s:DOCUMENT_ROOT',$v1,true);
V('S:SCRIPT_FILENAME',$v2,true);
V('s:SCRIPT_FILENAME',$v2,true);
}
// parse base url
/*
$p = V("s:SERVER_PORT")=='80' ? '' : ':'.V("s:SERVER_PORT");
$s = V("s:SCRIPT_NAME");
$baseUrl = 'http://' . V("s:HTTP_HOST") . $p . "/" . ltrim(substr($s,0,strrpos($s,"/")),"/");
define('W_BASE_URL',rtrim($baseUrl,"/ ") . "/" );
*/
$p = V("s:SERVER_PORT")=='80' ? '' : ':'.V("s:SERVER_PORT");
define('W_BASE_HTTP','http://' . V("s:HTTP_HOST") );
define('W_BASE_URL',preg_replace("#/[^/]+$#",'/',str_replace(V('S:DOCUMENT_ROOT'),'',V('S:SCRIPT_FILENAME'))));
define('W_BASE_FILENAME', basename(V('S:SCRIPT_FILENAME')));
}
//------------------------------------------------------------------
/**
* APP::request(); 处理用户请求
* @param $halt 执行完请求后是否退出
* @return 无返回值
*/
function request($halt=false){
APP::M(APP::getRequestRoute());
if ($halt) exit;
}
//------------------------------------------------------------------
/**
* APP::getRequestRoute(); 从当前请求中取得模块路由信息
* @param $is_acc 是否以数组的形式返回
* @return requestRoute
*/
function getRequestRoute($is_acc=false){
//--------------------------------------------------------------
$m = "";
if ( R_MODE == 0 ){
$m = APP::V("g:".R_GET_VAR_NAME);
$m = $m ? $m : R_DEF_MOD;
}
//--------------------------------------------------------------
if ( R_MODE == 1 ){
$m = ltrim(APP::V("s:PATH_INFO")," /");
$m = $m ? $m : R_DEF_MOD;
}
//--------------------------------------------------------------
if ( R_MODE == 2 ){
$ss = trim(V('S:PATH_INFO',''),'/');
if (empty($ss)) {
$m = R_DEF_MOD;
}else{
preg_match("#^([a-z_][a-z0-9_\./]*/|)([a-z0-9_]+)(?:\.([a-z_][a-z0-9_]*))?(?:/|\$)#sim",$ss,$mm);
//print_r($mm);
$m = trim($mm[0], '/');
}
}
//--------------------------------------------------------------
if ( R_MODE == 3 ){
$m = APP::V("g:".R_GET_VAR_NAME);
if ( empty($m) ){
$ss = trim(V('S:PATH_INFO',''),'/');
if (empty($ss)) {
$m = R_DEF_MOD;
}else{
preg_match("#^([a-z_][a-z0-9_\./]*/|)([a-z0-9_]+)(?:\.([a-z_][a-z0-9_]*))?(?:/|\$)#sim",$ss,$mm);
$m = trim($mm[0], '/');
}
}
}
//--------------------------------------------------------------
if (!empty($m)) {
if (!$is_acc) {
return $m;
}else{
$r = APP::_parseRoute($m);
return array('path'=>$r[1], 'class'=>$r[2], 'function'=>$r[3]);
}
}
//--------------------------------------------------------------
trigger_error("Unknow route type: [ ".R_TYPE." ]", E_USER_ERROR);
}
//------------------------------------------------------------------
/**
* APP::gerRuningRoute();
* 获取当前正在执行的 mRoute
* @param $is_acc 是否以数组的形式返回
*/
function getRuningRoute($is_acc=false){
$m = APP::getData('RuningRoute');
return ($is_acc) ? $m : $m['path'].$m['class'].".".$m['function'] ;
}
//------------------------------------------------------------------
/**
* APP::addPreAction($doRoute, $type, $args=false);
* 此方法必须在 APP::init();之前执行
* @param $doRoute 模块路由,如 demo/index.show
* @param $type 模块类型,可选值为: m , f , c ; 分别表示 模块 函数 和 类库
* @param $args 模块所需要的参数,统一用数据传递,$type 为 m 时无效
* @param $except 例外模块,在这些模块中 将不执行此预处理程序 默认为空 可以是数组或者字符串
* @return 无返回值
*/
function addPreDoAction($doRoute, $type, $args=array(), $except='') {
APP::setData($doRoute . ',' . $type, array($doRoute,$type, $args, $except), '_PreDoActions');
}
//------------------------------------------------------------------
/// 处理预加载模块
function _doPreActions() {
$as = APP::getData(false,'_PreDoActions');
if (empty($as) || !is_array($as)) {return true;}
foreach($as as $v ){
$route = trim($v[0]);
$type = strtoupper($v[1]);
$arg = $v[2];
$noRun = $v[3];
if (!empty($noRun)){
if (!is_array($noRun)) { $noRun = array($v[3]); }
//print_r($noRun);exit;
if (in_array(APP::getRequestRoute(),$noRun)){ continue;}
}
switch ($type) {
case 'M' :
APP::M($route);
break;
case 'C' :
$rData = APP::_parseRoute($route);
$c = APP::N($rData[2]);
$c->$rData[3]($arg);
break;
case 'F' :
APP::F($route,$arg);
break;
default :
trigger_error("Unknow preDoAction type: [ ".$type." ]", E_USER_ERROR);
break;
}
}
}
//------------------------------------------------------------------
/**
* APP::setData($k,$v=false,$category='STATIC_STORE');
* 保存一个静态全局数据
*/
function setData($k,$v=false,$category='STATIC_STORE'){
if (!is_array($GLOBALS[V_GLOBAL_NAME])){
$GLOBALS[V_GLOBAL_NAME] = array();
}
if (!is_array($GLOBALS[V_GLOBAL_NAME][$category])){
$GLOBALS[V_GLOBAL_NAME][$category] = array();
}
if (is_array($k)){
$GLOBALS[V_GLOBAL_NAME][$category] = array_merge($GLOBALS[V_GLOBAL_NAME][$category], $k);
}else{
$GLOBALS[V_GLOBAL_NAME][$category][$k] = $v;
}
}
//------------------------------------------------------------------
/**
* APP::getData($k=false, $category='STATIC_STORE');
* 获取一个静态存储数据
*/
function getData($k=false, $category='STATIC_STORE'){
if (!is_array($GLOBALS[V_GLOBAL_NAME][$category])){
$GLOBALS[V_GLOBA