/** * Ajax方式返回数据到客户端 * @access protected * @param mixed $data 要返回的数据 * @param String $type AJAX返回数据格式 * @return void */ protected function ajaxReturn($data, $type = '', $json_option = 0) { $data['referer'] = $data['url'] ? $data['url'] : ""; $data['state'] = $data['status'] ? "success" : "fail"; if (empty($type)) { $type = C('DEFAULT_AJAX_RETURN'); } switch (strtoupper($type)) { case 'JSON': // 返回JSON数据格式到客户端 包含状态信息 header('Content-Type:application/json; charset=utf-8'); exit(json_encode($data, $json_option)); case 'XML': // 返回xml格式数据 header('Content-Type:text/xml; charset=utf-8'); exit(xml_encode($data)); case 'JSONP': // 返回JSON数据格式到客户端 包含状态信息 header('Content-Type:application/json; charset=utf-8'); $handler = isset($_GET[C('VAR_JSONP_HANDLER')]) ? $_GET[C('VAR_JSONP_HANDLER')] : C('DEFAULT_JSONP_HANDLER'); exit($handler . '(' . json_encode($data, $json_option) . ');'); case 'EVAL': // 返回可执行的js脚本 header('Content-Type:text/html; charset=utf-8'); exit($data); case 'AJAX_UPLOAD': // 返回JSON数据格式到客户端 包含状态信息 header('Content-Type:text/html; charset=utf-8'); exit(json_encode($data, $json_option)); default: // 用于扩展其他返回格式数据 Hook::listen('ajax_return', $data); } }
/** * 应用程序初始化 * @access public * @return void */ public static function init() { // 加载动态应用公共文件和配置 load_ext_file(COMMON_PATH); // 日志目录转换为绝对路径 默认情况下存储到公共模块下面 C('LOG_PATH', realpath(LOG_PATH) . '/Common/'); // 定义当前请求的系统常量 define('NOW_TIME', $_SERVER['REQUEST_TIME']); define('REQUEST_METHOD', $_SERVER['REQUEST_METHOD']); define('IS_GET', REQUEST_METHOD == 'GET' ? true : false); define('IS_POST', REQUEST_METHOD == 'POST' ? true : false); define('IS_PUT', REQUEST_METHOD == 'PUT' ? true : false); define('IS_DELETE', REQUEST_METHOD == 'DELETE' ? true : false); // URL调度 Dispatcher::dispatch(); if (C('REQUEST_VARS_FILTER')) { // 全局安全过滤 array_walk_recursive($_GET, 'think_filter'); array_walk_recursive($_POST, 'think_filter'); array_walk_recursive($_REQUEST, 'think_filter'); } // URL调度结束标签 Hook::listen('url_dispatch'); define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' || !empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')]) ? true : false); // TMPL_EXCEPTION_FILE 改为绝对地址 C('TMPL_EXCEPTION_FILE', realpath(C('TMPL_EXCEPTION_FILE'))); return; }
/** * 运行框架 */ public static function run() { try { self::init(); Hook::init(BASE_PATH); Hook::listen('appBegin'); Hook::listen('routeParseUrl', array(Config::get('REWRITE_RULE'), Config::get('REWRITE_ON'))); //default route if (!defined('APP_NAME') || !defined('CONTROLLER_NAME') || !defined('ACTION_NAME')) { Route::parseUrl(Config::get('REWRITE_RULE'), Config::get('REWRITE_ON')); } //execute action $controller = '\\app\\' . APP_NAME . '\\controller\\' . CONTROLLER_NAME . 'Controller'; $action = ACTION_NAME; if (!class_exists($controller)) { throw new \Exception("Controller '{$controller}' not found", 404); } $obj = new $controller(); if (!method_exists($obj, $action)) { throw new \Exception("Action '{$controller}::{$action}()' not found", 404); } Hook::listen('actionBefore', array($obj, $action)); $obj->{$action}(); Hook::listen('actionAfter', array($obj, $action)); } catch (\Exception $e) { Hook::listen('appError', array($e)); } Hook::listen('appEnd'); }
/** * 发送数据到客户端 * @access protected * @param mixed $data 要返回的数据 * @param String $type 返回数据格式 * @param bool $return 是否返回数据 * @return void */ public static function send($data = '', $type = '', $return = false) { $type = strtolower($type ?: self::$type); $headers = ['json' => 'application/json', 'xml' => 'text/xml', 'html' => 'text/html', 'jsonp' => 'application/javascript', 'script' => 'application/javascript', 'text' => 'text/plain']; if (!headers_sent() && isset($headers[$type])) { header('Content-Type:' . $headers[$type] . '; charset=utf-8'); } $data = $data ?: self::$data; if (is_callable(self::$tramsform)) { $data = call_user_func_array(self::$tramsform, [$data]); } else { switch ($type) { case 'json': // 返回JSON数据格式到客户端 包含状态信息 $data = json_encode($data, JSON_UNESCAPED_UNICODE); break; case 'jsonp': // 返回JSON数据格式到客户端 包含状态信息 $handler = !empty($_GET[Config::get('var_jsonp_handler')]) ? $_GET[Config::get('var_jsonp_handler')] : Config::get('default_jsonp_handler'); $data = $handler . '(' . json_encode($data, JSON_UNESCAPED_UNICODE) . ');'; break; case '': // 类型为空不做处理 break; default: // 用于扩展其他返回格式数据 APP_HOOK && Hook::listen('return_data', $data); } } if ($return) { return $data; } echo $data; self::isExit() && exit; }
/** * 显示视图 * @param null $tplFile 模板文件 * @param int $cacheTime 缓存时间 * @param null $cachePath 缓存目录 * @param string $contentType 文件类型 * @param bool $show 是否显示 * @return mixed */ protected function display($tplFile = null, $cacheTime = -1, $cachePath = null, $contentType = "text/html", $show = true) { Hook::listen("VIEW_START"); //执行视图对象中的display同名方法 $status = $this->view->display($tplFile, $cacheTime, $cachePath, $contentType, $show); Hook::listen("VIEW_END"); return $status; }
public function notifyActionAction() { $params = array('payment_agent' => 'alipay', 'method' => 'notify_action', 'data' => $this->input); try { Hook::listen('process_payment', $event = new EventData($params)); if ($event->getData('result/0/error_code')) { throw new Exception(); } //$this->_ajaxReturn('success','200','EVAL'); echo "success"; } catch (Exception $e) { echo "fail"; } }
public function Login() { if (IS_POST) { if ($this->db->login()) { } else { $this->error($this->db->error); } //插件监听 Hook::listen('ADMIN_LOGIN_SUCCESS'); go("Index/index"); } else { //登录前监听插件 Hook::listen('ADMIN_LOGIN_START'); $this->display(); } }
/** * 运行应用 * @access public * @reutrn mixed */ public static function run() { //session处理 session(C("SESSION_OPTIONS")); //执行应用开始钓子 Hook::listen("APP_INIT"); //执行应用开始钓子 Hook::listen("APP_BEGIN"); //Debug Start DEBUG and Debug::start("APP_BEGIN"); self::start(); //Debug End DEBUG and Debug::show("APP_BEGIN", "APP_END"); //日志记录 !DEBUG and C('LOG_RECORD') and Log::save(); //应用结束钓子 Hook::listen("APP_END"); }
private static function init() { // 加载应用公共文件和配置 // C(include CONF_PATH . 'config' .CONF_EXT); // 定义当前请求的系统常量 define('NOW_TIME', $_SERVER['REQUEST_TIME']); define('REQUEST_METHOD', $_SERVER['REQUEST_METHOD']); define('IS_GET', REQUEST_METHOD == 'GET' ? true : false); define('IS_POST', REQUEST_METHOD == 'POST' ? true : false); define('IS_PUT', REQUEST_METHOD == 'PUT' ? true : false); define('IS_DELETE', REQUEST_METHOD == 'DELETE' ? true : false); define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' ? true : false); // URL调度 \Core\Dispatcher::run(); // URL调度结束标签 Hook::listen('url_dispatch'); //没有对应的行为函数,返回null notes by lwh 2015-11-19 return; }
public function __construct() { //设置字符集 header("Content-type:text/html;charset=" . Config::get('app.charset')); //时区 date_default_timezone_set(Config::get('app.timezone')); //路由处理 $this->ParseRoute(); //导入钓子 Hook::import(Config::get('hook')); //定义常量 $this->DefineConsts(); //应用开始钓子 Hook::listen("app_begin"); $this->ExecuteAction(); //应用结束钩子 Hook::listen("app_end"); //保存日志 Log::save(); }
public static function run() { self::_init(); //设置外部路径 //执行应用开始钓子 Hook::listen("APP_INIT"); //执行应用开始钓子 Hook::listen("APP_BEGIN"); set_error_handler(array(__CLASS__, 'error')); //接受php普通错误 register_shutdown_function(array(__CLASS__, 'fatal_error')); //接受致命错误 self::_user_import(); //加载用户自定义扩展 spl_autoload_register(array(__CLASS__, '_autoload')); //设置自动载入 self::_create_demo(); //创建一个demo self::_app_run(); //让应用默认跑起来 //应用结束钓子 Hook::listen("APP_END"); }
/** * URL调度 * @access public * * @param $config * * @throws Exception */ public static function dispatch($config) { if (isset($_GET[$config['var_pathinfo']])) { // 判断URL里面是否有兼容模式参数 $_SERVER['PATH_INFO'] = $_GET[$config['var_pathinfo']]; unset($_GET[$config['var_pathinfo']]); } elseif (IS_CLI) { // CLI模式下 index.php module/controller/action/params/... $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; } // 检测域名部署 if (!IS_CLI && !empty($config['url_domain_deploy'])) { if ($config['url_domain_rules']) { Route::domain($config['url_domain_rules']); } if ($match = Route::checkDomain()) { !defined('BIND_MODULE') && !empty($match[0]) && define('BIND_MODULE', $match[0]); !defined('BIND_CONTROLLER') && !empty($match[1]) && define('BIND_CONTROLLER', $match[1]); !defined('BIND_ACTION') && !empty($match[2]) && define('BIND_ACTION', $match[2]); } } // 监听path_info APP_HOOK && Hook::listen('path_info'); // 分析PATHINFO信息 if (!isset($_SERVER['PATH_INFO'])) { foreach ($config['pathinfo_fetch'] as $type) { if (!empty($_SERVER[$type])) { $_SERVER['PATH_INFO'] = 0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME']) ? substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; break; } } } // [模块,控制器,操作] $result = [null, null, null]; if (empty($_SERVER['PATH_INFO'])) { $_SERVER['PATH_INFO'] = ''; define('__INFO__', ''); define('__EXT__', ''); } else { $_SERVER['PATH_INFO'] = trim($_SERVER['PATH_INFO'], '/'); define('__INFO__', $_SERVER['PATH_INFO']); // URL后缀 define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'], PATHINFO_EXTENSION))); if (__INFO__) { if ($config['url_deny_suffix'] && preg_match('/\\.(' . $config['url_deny_suffix'] . ')$/i', __INFO__)) { throw new Exception('url suffix deny'); } // 去除URL后缀 $_SERVER['PATH_INFO'] = preg_replace($config['url_html_suffix'] ? '/\\.(' . trim($config['url_html_suffix'], '.') . ')$/i' : '/\\.' . __EXT__ . '$/i', '', __INFO__); $depr = $config['pathinfo_depr']; // 还原劫持后真实pathinfo $path_info = (defined('BIND_MODULE') ? BIND_MODULE . $depr : '') . (defined('BIND_CONTROLLER') ? BIND_CONTROLLER . $depr : '') . (defined('BIND_ACTION') ? BIND_ACTION . $depr : '') . $_SERVER['PATH_INFO']; // 路由检测 if (!empty($config['url_route_on'])) { // 开启路由 则检测路由配置 Route::register(!empty($config['route']) ? $config['route'] : null); $result = Route::check($path_info, $depr); if (false === $result) { // 路由无效 if ($config['url_route_must']) { throw new Exception('route not define '); } else { // 继续分析URL $result = Route::parseUrl($path_info, $depr); } } } else { // 分析URL地址 $result = Route::parseUrl($path_info, $depr); } } } if (APP_MULTI_MODULE) { $module = strtolower($result[0] ?: $config['default_module']); if ($maps = $config['url_module_map']) { if (isset($maps[$module])) { // 记录当前别名 define('MODULE_ALIAS', $module); // 获取实际的项目名 $module = $maps[MODULE_ALIAS]; } elseif (array_search($module, $maps)) { // 禁止访问原始项目 $module = ''; } } // 获取模块名称 define('MODULE_NAME', defined('BIND_MODULE') ? BIND_MODULE : strip_tags($module)); // 模块初始化 if (MODULE_NAME && !in_array(MODULE_NAME, $config['deny_module_list']) && is_dir(APP_PATH . MODULE_NAME)) { APP_HOOK && Hook::listen('app_begin'); define('MODULE_PATH', APP_PATH . MODULE_NAME . DS); define('VIEW_PATH', MODULE_PATH . VIEW_LAYER . DS); // 初始化模块 self::initModule(MODULE_NAME, $config); } else { throw new Exception('module [ ' . MODULE_NAME . ' ] not exists ', 10005); } } else { define('MODULE_NAME', ''); define('MODULE_PATH', APP_PATH); define('VIEW_PATH', MODULE_PATH . VIEW_LAYER . DS); } // 获取控制器名 $controller = strip_tags(strtolower($result[1] ?: Config::get('default_controller'))); define('CONTROLLER_NAME', defined('BIND_CONTROLLER') ? BIND_CONTROLLER : $controller); // 获取操作名 $action = strip_tags(strtolower($result[2] ?: Config::get('default_action'))); define('ACTION_NAME', defined('BIND_ACTION') ? BIND_ACTION : $action); }
/** * 编译模板文件内容 * @access protected * @param mixed $tmplContent 模板内容 * @return string */ protected function compiler($tmplContent) { //模板解析 $tmplContent = $this->parse($tmplContent); // 还原被替换的Literal标签 $tmplContent = preg_replace_callback('/<!--###literal(\\d+)###-->/is', array($this, 'restoreLiteral'), $tmplContent); // 添加安全代码 $tmplContent = '<?php if (!defined(\'THINK_PATH\')) exit();?>' . $tmplContent; // 优化生成的php代码 $tmplContent = str_replace('?><?php', '', $tmplContent); // 模版编译过滤标签 Hook::listen('template_filter', $tmplContent); return strip_whitespace($tmplContent); }
public function fetch($templateFile = '', $content = '', $prefix = '') { if (empty($content)) { $templateFile = $this->parseTemplate($templateFile); if (!is_file($templateFile)) { E(L('_TEMPLATE_NOT_EXIST_') . ':' . $templateFile); } } else { defined('THEME_PATH') or define('THEME_PATH', $this->getThemePath()); } ob_start(); ob_implicit_flush(0); if ('php' == strtolower(C('TMPL_ENGINE_TYPE'))) { $_content = $content; extract($this->tVar, EXTR_OVERWRITE); empty($_content) ? include $templateFile : eval('?>' . $_content); } else { $params = array('var' => $this->tVar, 'file' => $templateFile, 'content' => $content, 'prefix' => $prefix); Hook::listen('view_parse', $params); } $content = ob_get_clean(); Hook::listen('view_filter', $content); return $content; }
/** * 运行应用实例 入口文件使用的快捷方法 * @access public * @return void */ public static function run() { // 应用初始化标签 Hook::listen('app_init'); App::init(); // 应用开始标签 Hook::listen('app_begin'); // Session初始化 if (!IS_CLI) { session(C('SESSION_OPTIONS')); } // 记录应用初始化时间 G('initTime'); App::exec(); // 应用结束标签 Hook::listen('app_end'); return; }
public static function load() { Hook::listen('Application', new Module_Node_Listener_Application()); Controller::register('node', new Module_Node_Controller_Node()); }
/** * 删除文章 * @param $aid 文章aid * @return bool */ public function del($aid) { $ContentModel = ContentModel::getInstance($this->mid); $map['aid'] = array('IN', $aid); //删除文章静态文件 $content = $ContentModel->where($map)->find(); //执行删除 if ($ContentModel->del($aid)) { //删除文章tag $map['cid'] = $content['cid']; $map['aid'] = $content['aid']; M('content_tag')->where($map)->del(); Hook::listen('CONTENT_DEL'); return true; } else { $this->error = '删除文章失败'; } }
/** * 实时写入日志信息 并支持行为 * @param mixed $msg 调试信息 * @param string $type 信息类型 * @return bool */ public static function write($msg, $type = 'log') { if (!is_string($msg)) { $msg = var_export($msg, true); } // 封装日志信息 $log[] = ['type' => $type, 'msg' => $msg]; // 监听log_write APP_HOOK && Hook::listen('log_write', $log); if (is_null(self::$driver)) { self::init(Config::get('log')); } // 写入日志 return self::$driver->save($log); }
/** * URL调度 * @access public * @return void */ public static function dispatch($config) { if (isset($_GET[$config['var_pathinfo']])) { // 判断URL里面是否有兼容模式参数 $_SERVER['PATH_INFO'] = $_GET[$config['var_pathinfo']]; unset($_GET[$config['var_pathinfo']]); } elseif (IS_CLI) { // CLI模式下 index.php module/controller/action/params/... $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; } // 检测域名部署 if (!IS_CLI && isset($config['sub_domain_deploy']) && $config['sub_domain_deploy']) { Route::checkDomain(); } // 监听path_info Hook::listen('path_info'); // 分析PATHINFO信息 if (!isset($_SERVER['PATH_INFO']) && $_SERVER['SCRIPT_NAME'] != $_SERVER['PHP_SELF']) { $types = explode(',', $config['pathinfo_fetch']); foreach ($types as $type) { if (0 === strpos($type, ':')) { // 支持函数判断 $_SERVER['PATH_INFO'] = call_user_func(substr($type, 1)); break; } elseif (!empty($_SERVER[$type])) { $_SERVER['PATH_INFO'] = 0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME']) ? substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; break; } } } if (empty($_SERVER['PATH_INFO'])) { $_SERVER['PATH_INFO'] = ''; define('__INFO__', ''); define('__EXT__', ''); } else { $_SERVER['PATH_INFO'] = trim($_SERVER['PATH_INFO'], '/'); define('__INFO__', $_SERVER['PATH_INFO']); // URL后缀 define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'], PATHINFO_EXTENSION))); $_SERVER['PATH_INFO'] = __INFO__; if (__INFO__ && !defined('BIND_MODULE')) { if ($config['url_deny_suffix'] && preg_match('/\\.(' . $config['url_deny_suffix'] . ')$/i', __INFO__)) { throw new Exception('URL_SUFFIX_DENY'); } $paths = explode($config['pathinfo_depr'], __INFO__, 2); // 获取URL中的模块名 if ($config['require_module'] && !isset($_GET[VAR_MODULE])) { $_GET[VAR_MODULE] = array_shift($paths); $_SERVER['PATH_INFO'] = implode('/', $paths); } } // 去除URL后缀 $_SERVER['PATH_INFO'] = preg_replace($config['url_html_suffix'] ? '/\\.(' . trim($config['url_html_suffix'], '.') . ')$/i' : '/\\.' . __EXT__ . '$/i', '', $_SERVER['PATH_INFO']); } // 获取模块名称 define('MODULE_NAME', defined('BIND_MODULE') ? BIND_MODULE : self::getModule($config)); // 模块初始化 if (MODULE_NAME && MODULE_NAME != $config['common_module'] && is_dir(APP_PATH . MODULE_NAME)) { Hook::listen('app_begin'); define('MODULE_PATH', APP_PATH . MODULE_NAME . '/'); define('VIEW_PATH', MODULE_PATH . VIEW_LAYER . '/'); // 初始化模块 self::initModule(MODULE_PATH, $config); } else { throw new Exception('module not exists :' . MODULE_NAME); } // 路由检测和控制器、操作解析 Route::check($_SERVER['PATH_INFO'], $config['pathinfo_depr']); // 获取控制器名 define('CONTROLLER_NAME', strip_tags(strtolower(isset($_GET[VAR_CONTROLLER]) ? $_GET[VAR_CONTROLLER] : $config['default_controller']))); // 获取操作名 define('ACTION_NAME', strip_tags(strtolower(isset($_GET[VAR_ACTION]) ? $_GET[VAR_ACTION] : $config['default_action']))); unset($_GET[VAR_ACTION], $_GET[VAR_CONTROLLER], $_GET[VAR_MODULE]); //保证$_REQUEST正常取值 $_REQUEST = array_merge($_POST, $_GET, $_COOKIE); }
private static function parsePathinfo($config) { if (isset($_GET[$config['var_pathinfo']])) { // 判断URL里面是否有兼容模式参数 $_SERVER['PATH_INFO'] = $_GET[$config['var_pathinfo']]; unset($_GET[$config['var_pathinfo']]); } elseif (IS_CLI) { // CLI模式下 index.php module/controller/action/params/... $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; } // 监听path_info APP_HOOK && Hook::listen('path_info'); // 分析PATHINFO信息 if (!isset($_SERVER['PATH_INFO'])) { foreach ($config['pathinfo_fetch'] as $type) { if (!empty($_SERVER[$type])) { $_SERVER['PATH_INFO'] = 0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME']) ? substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; break; } } } }
public function del($aid) { $ContentModel = ContentModel::getInstance($this->mid); if ($ContentModel->del($aid)) { //删除文章tag属性 M('content_tag')->where(array('cid' => $this->cid))->del(); //生成栏目静态 $this->createCategoryHtml($this->cid); Hook::listen('content_del'); return true; } else { $this->error = '删除文章失败'; } }
/** * URL映射到控制器 * @access public * @return void */ public static function dispatch() { $varPath = C('VAR_PATHINFO'); $varAddon = C('VAR_ADDON'); $varModule = C('VAR_MODULE'); $varController = C('VAR_CONTROLLER'); $varAction = C('VAR_ACTION'); $urlCase = C('URL_CASE_INSENSITIVE'); if (isset($_GET[$varPath])) { // 判断URL里面是否有兼容模式参数 $_SERVER['PATH_INFO'] = $_GET[$varPath]; unset($_GET[$varPath]); } elseif (IS_CLI) { // CLI模式下 index.php module/controller/action/params/... $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; } // 开启子域名部署 if (C('APP_SUB_DOMAIN_DEPLOY')) { $rules = C('APP_SUB_DOMAIN_RULES'); if (isset($rules[$_SERVER['HTTP_HOST']])) { // 完整域名或者IP配置 define('APP_DOMAIN', $_SERVER['HTTP_HOST']); // 当前完整域名 $rule = $rules[APP_DOMAIN]; } else { if (strpos(C('APP_DOMAIN_SUFFIX'), '.')) { // com.cn net.cn $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -3); } else { $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -2); } if (!empty($domain)) { $subDomain = implode('.', $domain); define('SUB_DOMAIN', $subDomain); // 当前完整子域名 $domain2 = array_pop($domain); // 二级域名 if ($domain) { // 存在三级域名 $domain3 = array_pop($domain); } if (isset($rules[$subDomain])) { // 子域名 $rule = $rules[$subDomain]; } elseif (isset($rules['*.' . $domain2]) && !empty($domain3)) { // 泛三级域名 $rule = $rules['*.' . $domain2]; $panDomain = $domain3; } elseif (isset($rules['*']) && !empty($domain2) && 'www' != $domain2) { // 泛二级域名 $rule = $rules['*']; $panDomain = $domain2; } } } if (!empty($rule)) { // 子域名部署规则 '子域名'=>array('模块名[/控制器名]','var1=a&var2=b'); if (is_array($rule)) { list($rule, $vars) = $rule; } $array = explode('/', $rule); // 模块绑定 define('BIND_MODULE', array_shift($array)); // 控制器绑定 if (!empty($array)) { $controller = array_shift($array); if ($controller) { define('BIND_CONTROLLER', $controller); } } if (isset($vars)) { // 传入参数 parse_str($vars, $parms); if (isset($panDomain)) { $pos = array_search('*', $parms); if (false !== $pos) { // 泛域名作为参数 $parms[$pos] = $panDomain; } } $_GET = array_merge($_GET, $parms); } } } // 分析PATHINFO信息 if (!isset($_SERVER['PATH_INFO'])) { $types = explode(',', C('URL_PATHINFO_FETCH')); foreach ($types as $type) { if (0 === strpos($type, ':')) { // 支持函数判断 $_SERVER['PATH_INFO'] = call_user_func(substr($type, 1)); break; } elseif (!empty($_SERVER[$type])) { $_SERVER['PATH_INFO'] = 0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME']) ? substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; break; } } } $depr = C('URL_PATHINFO_DEPR'); define('MODULE_PATHINFO_DEPR', $depr); if (empty($_SERVER['PATH_INFO'])) { $_SERVER['PATH_INFO'] = ''; define('__INFO__', ''); define('__EXT__', ''); } else { define('__INFO__', trim($_SERVER['PATH_INFO'], '/')); // URL后缀 define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'], PATHINFO_EXTENSION))); $_SERVER['PATH_INFO'] = __INFO__; if (!defined('BIND_MODULE') && (!C('URL_ROUTER_ON') || !Route::check())) { if (__INFO__ && C('MULTI_MODULE')) { // 获取模块名 $paths = explode($depr, __INFO__, 2); $allowList = C('MODULE_ALLOW_LIST'); // 允许的模块列表 $module = preg_replace('/\\.' . __EXT__ . '$/i', '', $paths[0]); if (empty($allowList) || is_array($allowList) && in_array_case($module, $allowList)) { $_GET[$varModule] = $module; $_SERVER['PATH_INFO'] = isset($paths[1]) ? $paths[1] : ''; } } } } // URL常量 define('__SELF__', strip_tags($_SERVER[C('URL_REQUEST_URI')])); // 获取模块名称 define('MODULE_NAME', defined('BIND_MODULE') ? BIND_MODULE : self::getModule($varModule)); // 检测模块是否存在 if (MODULE_NAME && (defined('BIND_MODULE') || !in_array_case(MODULE_NAME, C('MODULE_DENY_LIST'))) && is_dir(APP_PATH . MODULE_NAME)) { // 定义当前模块路径 define('MODULE_PATH', APP_PATH . MODULE_NAME . '/'); // 定义当前模块的模版缓存路径 C('CACHE_PATH', CACHE_PATH . MODULE_NAME . '/'); // 定义当前模块的日志目录 C('LOG_PATH', realpath(LOG_PATH) . '/' . MODULE_NAME . '/'); // 模块检测 Hook::listen('module_check'); // 加载模块配置文件 if (is_file(MODULE_PATH . 'Conf/config' . CONF_EXT)) { C(load_config(MODULE_PATH . 'Conf/config' . CONF_EXT)); } // 加载应用模式对应的配置文件 if ('common' != APP_MODE && is_file(MODULE_PATH . 'Conf/config_' . APP_MODE . CONF_EXT)) { C(load_config(MODULE_PATH . 'Conf/config_' . APP_MODE . CONF_EXT)); } // 当前应用状态对应的配置文件 if (APP_STATUS && is_file(MODULE_PATH . 'Conf/' . APP_STATUS . CONF_EXT)) { C(load_config(MODULE_PATH . 'Conf/' . APP_STATUS . CONF_EXT)); } // 加载模块别名定义 if (is_file(MODULE_PATH . 'Conf/alias.php')) { Think::addMap(include MODULE_PATH . 'Conf/alias.php'); } // 加载模块tags文件定义 if (is_file(MODULE_PATH . 'Conf/tags.php')) { Hook::import(include MODULE_PATH . 'Conf/tags.php'); } // 加载模块函数文件 if (is_file(MODULE_PATH . 'Common/function.php')) { include MODULE_PATH . 'Common/function.php'; } // 加载模块的扩展配置文件 load_ext_file(MODULE_PATH); } else { E(L('_MODULE_NOT_EXIST_') . ':' . MODULE_NAME); } if (!defined('__APP__')) { $urlMode = C('URL_MODEL'); if ($urlMode == URL_COMPAT) { // 兼容模式判断 define('PHP_FILE', _PHP_FILE_ . '?' . $varPath . '='); } elseif ($urlMode == URL_REWRITE) { $url = dirname(_PHP_FILE_); if ($url == '/' || $url == '\\') { $url = ''; } define('PHP_FILE', $url); } else { define('PHP_FILE', _PHP_FILE_); } // 当前应用地址 define('__APP__', strip_tags(PHP_FILE)); } // 模块URL地址 $moduleName = defined('MODULE_ALIAS') ? MODULE_ALIAS : MODULE_NAME; define('__MODULE__', defined('BIND_MODULE') || !C('MULTI_MODULE') ? __APP__ : __APP__ . '/' . ($urlCase ? strtolower($moduleName) : $moduleName)); if ('' != $_SERVER['PATH_INFO'] && (!C('URL_ROUTER_ON') || !Route::check())) { // 检测路由规则 如果没有则按默认规则调度URL Hook::listen('path_info'); // 检查禁止访问的URL后缀 if (C('URL_DENY_SUFFIX') && preg_match('/\\.(' . trim(C('URL_DENY_SUFFIX'), '.') . ')$/i', $_SERVER['PATH_INFO'])) { send_http_status(404); exit; } // 去除URL后缀 $_SERVER['PATH_INFO'] = preg_replace(C('URL_HTML_SUFFIX') ? '/\\.(' . trim(C('URL_HTML_SUFFIX'), '.') . ')$/i' : '/\\.' . __EXT__ . '$/i', '', $_SERVER['PATH_INFO']); $depr = C('URL_PATHINFO_DEPR'); $paths = explode($depr, trim($_SERVER['PATH_INFO'], $depr)); if (!defined('BIND_CONTROLLER')) { // 获取控制器 if (C('CONTROLLER_LEVEL') > 1) { // 控制器层次 $_GET[$varController] = implode('/', array_slice($paths, 0, C('CONTROLLER_LEVEL'))); $paths = array_slice($paths, C('CONTROLLER_LEVEL')); } else { $_GET[$varController] = array_shift($paths); } } // 获取操作 if (!defined('BIND_ACTION')) { $_GET[$varAction] = array_shift($paths); } // 解析剩余的URL参数 $var = array(); if (C('URL_PARAMS_BIND') && 1 == C('URL_PARAMS_BIND_TYPE')) { // URL参数按顺序绑定变量 $var = $paths; } else { preg_replace_callback('/(\\w+)\\/([^\\/]+)/', function ($match) use(&$var) { $var[$match[1]] = strip_tags($match[2]); }, implode('/', $paths)); } $_GET = array_merge($var, $_GET); } // 获取控制器的命名空间(路径) define('CONTROLLER_PATH', self::getSpace($varAddon, $urlCase)); // 获取控制器和操作名 define('CONTROLLER_NAME', defined('BIND_CONTROLLER') ? BIND_CONTROLLER : self::getController($varController, $urlCase)); define('ACTION_NAME', defined('BIND_ACTION') ? BIND_ACTION : self::getAction($varAction, $urlCase)); // 当前控制器的UR地址 $controllerName = defined('CONTROLLER_ALIAS') ? CONTROLLER_ALIAS : CONTROLLER_NAME; define('__CONTROLLER__', __MODULE__ . $depr . (defined('BIND_CONTROLLER') ? '' : ($urlCase ? parse_name($controllerName) : $controllerName))); // 当前操作的URL地址 define('__ACTION__', __CONTROLLER__ . $depr . (defined('ACTION_ALIAS') ? ACTION_ALIAS : ACTION_NAME)); //保证$_REQUEST正常取值 $_REQUEST = array_merge($_POST, $_GET, $_COOKIE); // -- 加了$_COOKIE. 保证哦.. }
/** * 有返回结果的查询 * * @param $sql * @param array $params * * @return bool * @throws \Exception */ public function query($sql, array $params = []) { $this->query->build()->reset(); //准备sql $sth = $this->getLink(FALSE)->prepare($sql); //设置保存数据 $sth->setFetchMode(PDO::FETCH_ASSOC); //绑定参数 $params = $this->setParamsSort($params); foreach ((array) $params as $key => $value) { $sth->bindParam($key, $params[$key], is_numeric($params[$key]) ? PDO::PARAM_INT : PDO::PARAM_STR); } try { //执行查询 $sth->execute(); $this->affectedRow = $sth->rowCount(); //记录日志 if (DEBUG) { self::$queryLog[] = $sql . var_export($params, TRUE); } //触发钩子 Hook::listen('database_query', ['sql' => $sql, 'params' => $params]); return $sth->fetchAll() ?: []; } catch (Exception $e) { if (DEBUG) { $error = $sth->errorInfo(); throw new Exception($sql . " ;BindParams:" . var_export($params, TRUE) . implode(';', $error)); } else { return FALSE; } } }
/** * Ajax方式返回数据到客户端 * @access protected * @param mixed $data 要返回的数据 * @param String $type AJAX返回数据格式 * @param int $json_option 传递给json_encode的option参数 * @return void */ function ajaxReturn($data, $type = '', $json_option = 0) { if (empty($type)) { $type = 'JSON'; } switch (strtoupper($type)) { case 'JSON': // 返回JSON数据格式到客户端 包含状态信息 header('Content-Type:application/json; charset=utf-8'); exit(json_encode($data, $json_option)); case 'XML': // 返回xml格式数据 header('Content-Type:text/xml; charset=utf-8'); exit(xml_encode($data)); case 'JSONP': // 返回JSON数据格式到客户端 包含状态信息 header('Content-Type:application/json; charset=utf-8'); $handler = isset($_GET['callback']) ? $_GET['callback'] : 'jsonpReturn'; exit($handler . '(' . json_encode($data, $json_option) . ');'); case 'EVAL': // 返回可执行的js脚本 header('Content-Type:text/html; charset=utf-8'); exit($data); default: // 用于扩展其他返回格式数据 Hook::listen('ajax_return', $data); } }
/** * 解析和获取模板内容 用于输出 * @access public * @param string $templateFile 模板文件名 * @param string $content 模板输出内容 * @param string $prefix 模板缓存前缀 * @return string */ public function fetch($templateFile = '', $content = '', $prefix = '') { if (empty($content)) { $templateFile = $this->parseTemplate($templateFile); // 模板文件不存在直接返回 if (!is_file($templateFile)) { E(L('_TEMPLATE_NOT_EXIST_') . ':' . $templateFile); } } else { defined('THEME_PATH') or define('THEME_PATH', $this->getThemePath()); } // 页面缓存 ob_start(); ob_implicit_flush(0); if ('php' == strtolower(C('TMPL_ENGINE_TYPE'))) { // 使用PHP原生模板 $_content = $content; // 模板阵列变量分解成为独立变量 extract($this->tVar, EXTR_OVERWRITE); // 直接载入PHP模板 empty($_content) ? include $templateFile : eval('?>' . $_content); } else { // 视图解析标签 $params = array('var' => $this->tVar, 'file' => $templateFile, 'content' => $content, 'prefix' => $prefix); Hook::listen('view_parse', $params); } // 获取并清空缓存 $content = ob_get_clean(); // 内容过滤标签 Hook::listen('view_filter', $content); // 输出模板文件 return $content; }
/** * 实时写入日志信息 并支持行为 * @param mixed $msg 调试信息 * @param string $type 信息类型 * @return void */ public static function write($msg, $type = 'log') { if (!is_string($msg)) { $msg = print_r($msg, true); } // 封装日志信息 $log[] = ['type' => $type, 'msg' => $msg]; // 监听log_write APP_HOOK && Hook::listen('log_write', $log); // 写入日志 self::$driver && self::$driver->save($log); }
/** * 析构方法 * * @access public */ public function __destruct() { // 执行后续操作 Hook::listen('action_end'); }
/** * 析构函数 */ public function __destruct() { Hook::listen('CONTROLLER_END', $this->options); }
/** * 错误输出 * * @param mixed $error 错误 * @param int $code * * @internal param int $errno 错误代码 */ public static function halt($error, $code = 1) { $message = is_array($error) ? $error['message'] : $error; $code = is_array($error) ? $error['code'] : $code; $e = ['mssage' => $message, 'code' => $code]; if (APP_DEBUG) { //调试模式下输出错误信息 if (!is_array($error)) { $trace = debug_backtrace(); $e['message'] = $error; $e['file'] = $trace[0]['file']; $e['line'] = $trace[0]['line']; ob_start(); debug_print_backtrace(); $e['trace'] = ob_get_clean(); } else { $e = $error; } } elseif (!IS_API) { //否则定向到错误页面 $error_page = Config::get('error_page'); if (!empty($error_page)) { header('Location: ' . $error_page); } else { $e['message'] = Config::get('show_error_msg') ? $message : Config::get('error_message'); } } $type = Config::get('default_return_type'); if (!IS_API && 'html' == $type) { include Config::get('exception_tmpl'); } else { // 异常信息输出监听 APP_HOOK && Hook::listen('error_output', $e); // 输出异常内容 Response::returnData($e, $type); } exit; }
/** * 解析和获取模板内容 用于输出 * @access public * * @param string $template 模板文件名或者内容 * @param array $vars 模板输出变量 * @param array $config 模板参数 * @param bool $renderContent 是否渲染内容 * * @return string * @throws Exception */ public function fetch($template = '', $vars = [], $config = [], $renderContent = false) { // 模板变量 $vars = $vars ? $vars : $this->data; if (!$renderContent) { // 获取模板文件名 $template = $this->parseTemplate($template); // 开启调试模式Win环境严格区分大小写 // 模板不存在 抛出异常 if (!is_file($template) || APP_DEBUG && IS_WIN && realpath($template) != $template) { throw new Exception('template file not exists:' . $template, 10700); } // 记录视图信息 APP_DEBUG && Log::record('[ VIEW ] ' . $template . ' [ ' . var_export($vars, true) . ' ]', 'info'); } // 页面缓存 ob_start(); ob_implicit_flush(0); if ('php' == $this->engine || empty($this->engine)) { // 原生PHP解析 extract($vars, EXTR_OVERWRITE); is_file($template) ? include $template : eval('?>' . $template); } else { // 指定模板引擎 $this->engine->fetch($template, $vars, $config); } // 获取并清空缓存 $content = ob_get_clean(); // 内容过滤标签 APP_HOOK && Hook::listen('view_filter', $content); // 允许用户自定义模板的字符串替换 if (!empty($this->config['parse_str'])) { $replace = $this->config['parse_str']; $content = str_replace(array_keys($replace), array_values($replace), $content); } if (!Config::get('response_auto_output')) { // 自动响应输出 return Response::send($content, Response::type()); } return $content; }