/** * 顶层错误处理 */ public static function getTopErrors($code, $content = '', $file = '', $line = '') { if (empty($content)) { return false; } //运行错误不报告 if (stripos($content, '__runtime') || stripos($file, '__runtime')) { return false; } self::$errorList[] = array($code, $content, $file, $line); //触发错误发生是钩子函数 CHooks::callHooks(HOOKS_ERROR_HAPPEN, $code, $content, $file, $line); }
/** * 驱动模板 */ protected function display($templateName = null, $isCache = false, $num = '') { // 确定模板名称 if (false == stripos($templateName, '.html')) { $templateName = $templateName . '.html'; } if (isset($this->layout) && !empty($this->layout) && false == stripos($this->layout, '.html')) { $this->layout = $this->layout . '.html'; } else { $this->layout = null; } // 编译模板时 获取视图对象 $viewObject = $this->getView(); // 没有布局模板时则置空 if (null != $templateName) { if (false == $isCache) { $viewObject->clear_cache("layout/" . $this->layout, $templateName . $num); // 清除缓存 $viewObject->clear_cache($templateName, $templateName . $num); } // 装载模板 if ($viewObject->template_exists($templateName)) { $viewObject->assign('pageInfo', $this->pageInfo); if (isset($this->layout) && $this->layout != '') { $viewObject->assign('CONTENT_INSERET_LAYOUT', $templateName); $viewObject->display("layout/" . $this->layout, $templateName . $num); } else { $viewObject->display($templateName, $templateName . $num); } } else { throw new CViewException('[视图错误]使用的视图文件不存在 : ' . $templateName); } } // 调用访问视图后的钩子函数 CHooks::callHooks(HOOKS_VIEW_SHOW, $templateName); }
/** * 请求结束 */ public static function webShutdown() { //传递引起脚本中断的致命错误 $lastError = error_get_last(); if (!empty($lastError) && in_array($lastError['type'], array(E_USER_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, E_ERROR))) { CException::getTopErrors($lastError['type'], $lastError['message'], $lastError['file'], $lastError['line']); } //脚本因错误而中断 if (true == CException::hasFatalErrors()) { //最后发生的错误 $lastError = error_get_last(); //设置503请求头 CResponse::getInstance()->setHttpCode(503, false); } //触发执行结束钩子函数 CHooks::callHooks(HOOKS_SYSTEM_SHUTDOWN, CException::$errorList); //是否使用CMyFrame 默认错误呈现 if (true == CException::getErrorShow()) { //使用CMyFrame 默认进行错误呈现 CException::showErrorsView(); } }
/** * 读取缓存 */ public function get($key) { if (empty($key)) { throw new CacheException('[缓存错误]请指定读取缓存的key'); } //直接返回的数据 $data = $this->_cacheObject->get($key); $content = unserialize($data); //结果对象 $cacheItemObject = new CacheItem(); $cacheItemObject->setKey($key); $cacheItemObject->setValue($content); //触发获取缓存时的Hooks CHooks::callHooks(HOOKS_CACHE_GET, $cacheItemObject); //经过HOOKS的数据 $endContent = $cacheItemObject->getValue(); return !empty($endContent) ? $endContent : null; }
/** * 阻止敏感URL函数 */ static function StopAttack($StrFiltKey, $StrFiltValue, $ArrFiltReq) { if (is_array($StrFiltValue)) { $StrFiltValue = implode($StrFiltValue); } if (preg_match("/" . $ArrFiltReq . "/is", $StrFiltValue) == 1) { trigger_error('[安全错误]服务器拒绝执行该请求', E_ERROR); //触发控制器实例化完成的钩子函数 CHooks::callHooks(HOOKS_SAFE_URL, $ArrFiltReq, $StrFiltValue); exit; } }
/** * 构造 */ public function __construct($viewName) { $this->_viewName = $viewName; $viewConfigs = CConfig::getInstance()->load('TEMPLATE'); if (!isset($viewConfigs[$viewName])) { trigger_error('[视图错误]使用配置中不存在的模板引擎:' . $viewName, E_USER_ERROR); } $thisViewConfig = $viewConfigs[$viewName]; $templatePath = isset($thisViewConfig['TEMPLATE_PATH']) ? $thisViewConfig['TEMPLATE_PATH'] : ''; $viewConfItem = isset($thisViewConfig['CONF_INFO']) ? $thisViewConfig['CONF_INFO'] : array(); if (!file_exists($templatePath)) { trigger_error('[视图错误]未能找到指定模板引擎[' . $viewName . ']的主文件:' . $templatePath, E_USER_ERROR); } CLoader::importFile($templatePath); $viewObject = new $viewName(); if ('smarty' == $viewName) { $viewObject->template_dir = $viewConfItem['template_dir']; //编译目录 $compile_dir = $viewConfItem['compile_dir']; if (!is_dir($compile_dir)) { if (false == mkdir($compile_dir, true, 0755)) { echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>[部署错误]CMyFrame无法创建缓存目录,请确定服务器权限'; exit; } chmod($compile_dir, 0777); } $viewObject->compile_dir = $compile_dir; //缓存目录 $cache_dir = $viewConfItem['cache_dir']; if (!is_dir($cache_dir)) { if (false == mkdir($cache_dir, true, 0755)) { echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>[部署错误]CMyFrame无法创建缓存目录,请确定服务器权限'; exit; } chmod($cache_dir, 0777); } $viewObject->cache_dir = $cache_dir; //分隔符 $viewObject->left_delimiter = $viewConfItem['left_delimiter']; $viewObject->right_delimiter = $viewConfItem['right_delimiter']; //使用PHP语法 $viewObject->allow_php_tag = $viewConfItem['allow_php_tag']; //缓冲 $viewObject->caching = $viewConfItem['caching']; $viewObject->cache_lifetime = $viewConfItem['cache_lifetime']; //注册函数 $viewObject->register_function('url', array('CRequest', 'createUrl')); $viewObject->register_function('PageInfo', array('CSmarty', 'showPageData')); $viewObject->register_function('substr', array('CSmarty', 'cn_substr')); $viewObject->register_function('sayTime', array('CSmarty', 'sayTime')); //注册块函数 $viewObject->register_block('checkRight', array('CSmarty', 'checkRight')); //设置默认数据 CSmarty::setInitData($viewObject); } else { //设置所有配置项 foreach ((array) $viewConfItem as $key => $val) { $viewObject->{$key} = $val; } } //第一次获取视图时 CHooks::callHooks(HOOKS_VIEW_GET, $viewObject); $this->_viewObject = $viewObject; }
/** * 获取钩子列表 */ public static function getHooksList() { self::$_allHooks = array(); }
/** * execute 参数重载 */ private function _executeParam1($where) { if (empty($this->prepare)) { throw new CDbException('[查询错误]在函数中[CBuilder->prepare]传递参数错误'); } try { $btime = microtime(true); $databaseObject = CDatabase::getDatabase($this->configName); $this->_sql = $this->prepare; CHooks::callHooks(HOOKS_EXECUTE_BEFORE, $this); $prepareObject = $databaseObject->prepare($this->_sql); $prepareObject->execute($where); $rsReult = $prepareObject->fetchAll(); $etime = microtime(true); } catch (PDOException $pdoException) { throw new CDbException($pdoException->getMessage()); } $resultObject = new CResult(); $resultObject->setSql($this->prepare); $resultObject->setValue($rsReult); $resultObject->setCastTime($etime > $btime ? round($etime - $btime, 6) : 0); CHooks::callHooks(HOOKS_EXECUTE_END, $resultObject); //缓存结果 if (!empty($this->_cache)) { $cacheData = Cache::getInstance()->set($this->_cache, $resultObject, $this->_cacheTime); } $this->_clearSelf(); return $resultObject; }
/** * 获取PDO对象 */ public static function getDatabase($configName = 'main', $isMaster = true) { if (empty($configName)) { $configName = 'main'; } if (isset(self::$objectPdo[intval($isMaster) . $configName])) { return self::$objectPdo[intval($isMaster) . $configName]; } $dbConfig = CConfig::getInstance()->load('DB.' . $configName); if (!isset($dbConfig['master'])) { throw new CDbException('[配置错误]getDataBase方法尝试获取不存在的配置项:[Config->DB->master]'); } if (true == $isMaster) { $thisConfigData = $dbConfig['master']; self::$configData[intval($isMaster) . $configName] = $thisConfigData; self::$configData[intval(!$isMaster) . $configName] = $dbConfig['slaves']; } if (false == $isMaster) { $thisConfigData = !isset($dbConfig['slaves']) ? $dbConfig['master'] : $dbConfig['slaves']; self::$configData[intval($isMaster) . $configName] = $thisConfigData; self::$configData[intval(!$isMaster) . $configName] = $dbConfig['master']; } try { $pdoObject = new PDO($thisConfigData['connectionString'], $thisConfigData['username'], $thisConfigData['password']); $pdoObject->query('set names ' . $thisConfigData['charset']); } catch (PDOException $pdoException) { //尝试启用备用库 if (true == $isMaster) { //是否允许启用备库 $writeConf = self::$configData[intval($isMaster) . $configName]; if (isset($writeConf['slavesWrite']) && true == $writeConf['slavesWrite']) { //尝试连接备库 try { //从库配置 $slaverConf = self::$configData[intval(!$isMaster) . $configName]; $pdoObject = new PDO($slaverConf['connectionString'], $slaverConf['username'], $slaverConf['password']); $pdoObject->query('set names ' . $slaverConf['charset']); } catch (PDOException $pdoExceptionAgain) { $dbError = new CDBError(); $dbError->setSQLErrorCode('CMyFrame'); $dbError->setDriverErrorCode('CMyFrame'); $dbError->setErrorMessage('主库连接失败后,尝试连接从库,连接从库依旧失败'); CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError); //切换数据依旧无法连接 throw new CDbException('[数据库错误]主库连接失败后,尝试连接从库依旧失败:' . $pdoExceptionAgain->getMessage()); } } else { //不允许使用备库 $dbError = new CDBError(); $dbError->setSQLErrorCode('CMyFrame'); $dbError->setDriverErrorCode('CMyFrame'); $dbError->setErrorMessage('主库连接失败后,不允许尝试连接从库'); CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError); throw new CDbException('[数据库错误]连接主数据库失败,且不允许尝试使用从库:' . $pdoException->getMessage()); } } else { //是否使用主库进行读取 $readConf = self::$configData[intval($isMaster) . $configName]; if (isset($readConf['masterRead']) && true == $readConf['masterRead']) { $errorMessage = '从库连接失败后,尝试连接主库,主库连接成功'; try { //主库配置 $masterConf = self::$configData[intval(!$isMaster) . $configName]; $pdoObject = new PDO($masterConf['connectionString'], $masterConf['username'], $masterConf['password']); $pdoObject->query('set names ' . $masterConf['charset']); } catch (PDOException $pdoExceptionAgain) { $dbError = new CDBError(); $dbError->setSQLErrorCode('CMyFrame'); $dbError->setDriverErrorCode('CMyFrame'); $dbError->setErrorMessage('从库连接失败后,尝试连接主库,连接主库依旧失败'); CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError); //切换数据依旧无法连接 throw new CDbException('[数据库错误]从库连接失败后,尝试连接主库依旧失败:' . $pdoExceptionAgain->getMessage()); } } else { //发生SQL错误时 触发钩子 $dbError = new CDBError(); $dbError->setSQLErrorCode('CMyFrame'); $dbError->setDriverErrorCode('CMyFrame'); $dbError->setErrorMessage('从库连接失败后,不允许尝试连接主库'); CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError); throw new CDbException('[数据库错误]连接从数据库失败,且不允许尝试使用主库:' . $pdoException->getMessage()); } //发生SQL错误时 触发钩子 $dbError = new CDBError(); $dbError->setSQLErrorCode('CMyFrame'); $dbError->setDriverErrorCode('CMyFrame'); $dbError->setErrorMessage($errorMessage); CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError); } } self::$objectPdo[intval($isMaster) . $configName] = $pdoObject; return $pdoObject; }
/** * 创建符合重写的链接 */ public static function createUrl($params = array()) { //调用路由解析类创建URL $baseUrl = CRouteParse::url($params); //触发创建URL完成的钩子函数 $urlObject = new CUrl(); $urlObject->setUrl($baseUrl); $urlObject->setParam($params); CHooks::callHooks(HOOKS_URL_CREATE, $urlObject); //返回经过Hooks处理的URL return $urlObject->getUrl(); }