/** * 渲染输出 * * 3种模板刷新更新机制: * 1、配置webRun.view.refresh,(子)模板有修改会自动刷新,较耗资源适合开发环境 * 2、配置webRun.view.life,缓存操作生存期限后,自动删除重建 * 3、统一通过管理后台,刷新模板缓存 */ public function render($view, $ajaxDelimiter = NULL) { $this->initEngine($view, $ajaxDelimiter); $cacheFile = $this->_engineInstance->getCacheFilePath(); if (!file_exists($cacheFile)) { //缓存文件不存在 $this->_engineInstance->parse()->writeCompiled(); } elseif (Front::getInstance()->getAppConfig()->getByKey('webRun.view.refresh')) { //开启模板自动扫描刷新 $cacheStamp = filemtime($cacheFile); $tplStamp = filemtime($this->_engineInstance->getTplFilePath()); $tplStampList = array($tplStamp); //主模板未更新,检测子模板 if ($tplStamp <= $cacheStamp) { $subStampList = $this->_engineInstance->getSubTplStamp(); $tplStampList = array_merge($tplStampList, $subStampList); } if (max($tplStampList) > $cacheStamp) { unlink($cacheFile); $this->_engineInstance->parse()->writeCompiled(); } } elseif (Front::getInstance()->getAppConfig()->getByKey('webRun.view.life')) { //配置了自动过期时间 $lifeTime = Front::getInstance()->getAppConfig()->getByKey('webRun.view.life'); if (time() - filemtime($cacheFile) >= $lifeTime) { unlink($cacheFile); $this->_engineInstance->parse()->writeCompiled(); } } include $this->_engineInstance->getCacheFilePath(); }
/** * 增加一条日志信息 * * @param string $message * @param bool $trace 是否添加调试信息 */ public function add($message, $isTrace = TRUE) { $logInfo = array('log' => $message); if ($isTrace) { $trace = self::getDebugTrace(2); //过滤两级 if (!empty($trace)) { //保留最近一条执行路径 $logInfo['trace'] = array_shift($trace); } } $logInstance = SystemLog::create()->createRow(); $logInstance['UrlNow'] = Param::getRequestUrl(); $logInstance['Type'] = $this->type; $logInstance['Identify'] = $this->identify; $logInstance['Info'] = json_encode($logInfo); $request = Front::getInstance()->getRequest(); $logInstance['Package'] = $request->getPackageRouteSeg(); $logInstance['Control'] = $request->getControllerRouteSeg(); $logInstance['Action'] = $request->getActionRouteSeg(); $logInstance['Uid'] = $this->getLoginUid(); $logInstance['CreateTime'] = DateTime::format(); $this->buffer[] = $logInstance; $this->iter++; //超出缓存允许长度、超出缓存生命期输出到磁盘 if ($this->needFulsh()) { $this->flush(); } return $this; }
/** * 获取cdn配置 */ protected function getConfig() { $config = Front::getInstance()->getAppConfig()->getByKey('cdn'); if (!isset($config['app_id']) || !isset($config['app_secret']) || !isset($config['upload']) || !isset($config['manage'])) { throw new Exception('App.ini cdn config section is required.'); } return $config; }
/** * 初始化渲染引擎 */ protected function initEngine($view, $ajaxDelimiter = NULL) { $this->_engineInstance = new \HuiLib\View\TemplateEngine($view, $ajaxDelimiter); $viewConfig = Front::getInstance()->getAppConfig()->getByKey('webRun.view'); if (empty($viewConfig['viewPath']) || empty($viewConfig['cachePath'])) { throw new \HuiLib\Error\Exception("请在网站配置中同时添加webRun.view.viewPath和webRun.view.cachePath路径"); } $this->_engineInstance->setViewPath($viewConfig['viewPath']); $this->_engineInstance->setCachePath($viewConfig['cachePath']); }
/** * 完整性加密 * * @param array $data * @param string $secret */ public static function decrypt($post, $secret) { if (!is_array($post) || empty($post['hash']) || empty($secret)) { throw new \Exception(Front::getInstance()->getHuiLang()->_('cdn.decrypt.data.error')); } $hash = $post['hash']; unset($post['hash']); ksort($post, SORT_STRING); $post['app_secret'] = $secret; return $hash == md5(http_build_query($post)); }
public function route() { $request = Front::getInstance()->getRequest(); $name = $request->getRouteSegNum(RequestBase::SEG_ACTION); $this->nameBack = $name; $appConfig = Front::getInstance()->getAppConfig(); $baseCalss = $appConfig->getByKey('webRun.route.Action.Base'); if (empty($baseCalss) && !method_exists($baseCalss, 'dispatch')) { throw new \HuiLib\Error\RouteActionException('App.ini webRun.route.Action.Base not set or available.'); } $baseCalss::dispatch(); //重新出发路由 Front::getInstance()->getController()->reDispatch(); }
public static function exceptionHandle($exception) { $handle = Front::getInstance()->getAppConfig()->getByKey('webRun.error.handler'); if ($handle) { $controller = new $handle(); $controller->exceptionAction($exception); } else { echo "The page you found is not available right now."; if (ini_get('display_errors')) { echo '<pre>' . var_export($exception, true) . '</pre>'; } } exit; }
/** * 测试通过静态函数获取 */ private function testStaticInit() { $cache = \HuiLib\Cache\CacheBase::getDefault(Front::getInstance()->getAppConfig()); echo $cache->toString(); $cache->add('hanhui2', date('Y-m-d H:i:s')); echo $cache->get('hanhui2'); //测试数组 $cache->replace('array', Front::getInstance()->getAppConfig()->getByKey('cache.memcache')); \HuiLib\Helper\Debug::out($cache->get('array')); $cache->add('count', 0); $cache->increase('count'); echo $cache->get('count'); $cache = \HuiLib\Cache\CacheBase::getRedis(Front::getInstance()->getAppConfig()); echo $cache->toString(); $cache = \HuiLib\Cache\CacheBase::getMemcache(Front::getInstance()->getAppConfig()); echo $cache->toString(); $cache = \HuiLib\Cache\CacheBase::getApc(Front::getInstance()->getAppConfig()); echo $cache->toString(); $cache = \HuiLib\Cache\CacheBase::getFile(Front::getInstance()->getAppConfig()); echo $cache->toString(); }
/** * 增加一条日志信息 * * @param string $message * @param bool $trace 是否添加调试信息 */ public function add($message, $isTrace = FALSE) { //初始化储存文件 $this->getFileFd(); $logInfo = array(); $mtime = number_format(microtime(1), 4, '.', ''); $logInfo['Time'] = date("[H:i:s") . substr($mtime, strrpos($mtime, '.')); $request = Front::getInstance()->getRequest(); if ($request->getPackageRouteSeg() && $request->getControllerRouteSeg()) { $logInfo['Route'] = " {$request->getPackageRouteSeg()}/{$request->getControllerRouteSeg()}/{$request->getActionRouteSeg()}"; } $logInfo['Append'] = ']:'; if (!is_string($message)) { if (is_array($message)) { $message = json_encode($message); } else { $message = var_export($message, TRUE); } } $logInfo['Info'] = " {$message}"; if ($isTrace) { $trace = self::getDebugTrace(1); //过滤两级 $traceInfo = array('file' => '', 'line' => ''); if (!empty($trace)) { //保留最近一条执行路径 $traceInfo = array_shift($trace); } $logInfo['Trace'] = " Trace::{$traceInfo['file']}:{$traceInfo['line']}"; } $logInfo['End'] = PHP_EOL; $log = implode('', $logInfo); $this->buffer[] = $log; $this->iter++; //超出缓存允许长度、超出缓存生命期输出到磁盘 if ($this->needFulsh()) { $this->flush(); } return $this; }
public function init() { if (!isset($_SERVER['argv'][1])) { $_SERVER['argv'][1] = ''; } if (isset($_SERVER['argv'][2])) { $_SERVER['QUERY_STRING'] = $_SERVER['argv'][2]; $_SERVER['REQUEST_URI'] = '/' . $_SERVER['argv'][1] . '?' . $_SERVER['argv'][2]; parse_str($_SERVER['argv'][2], $params); //将请求参数覆盖到变量中 if ($params) { foreach ($params as $key => $value) { $_GET[$key] = $value; } } } //print_r($_SERVER);die(); $this->scriptUrl = (substr($_SERVER['argv'][1], 0, 1) === '/' ? '' : '/') . $_SERVER['argv'][1]; $this->httpHost = Front::getInstance()->getAppConfig()->getByKey('app.domain'); //设置路由资源定位符,并初始化路由信息 $this->routeUri = $this->httpHost . $this->scriptUrl; $this->initRouteInfo(); }
protected function preCheck() { try { $huiLang = Front::getInstance()->getHuiLang(); $appId = Param::post('app_id', Param::TYPE_STRING); if (!$appId) { return $this->format(self::API_FAIL, $huiLang->_('cdn.upload.app_id.null')); } if (empty($_FILES)) { return $this->format(self::API_FAIL, $huiLang->_('cdn.upload.files.empty')); } $secret = $this->getAppSecret($appId); $post = $this->remapPostArray($_POST); //字符安全解密 if (!Utility::decrypt($post, $secret)) { return $this->format(self::API_FAIL, $huiLang->_('cdn.upload.decode.failed')); } $config = $this->getConfig(); //上传文件校验处理 一个有错,全部终止 foreach ($_FILES as $key => $file) { $meta = Param::post($key, Param::TYPE_ARRAY); if (empty($meta['size']) || empty($meta['type']) || empty($meta['name']) || empty($meta['sha1'])) { return $this->format(self::API_FAIL, $huiLang->_('cdn.upload.files.error')); } if ($file['error'] || $file['size'] != $meta['size'] || sha1_file($file['tmp_name']) != $meta['sha1']) { return $this->format(self::API_FAIL, $huiLang->_('cdn.upload.files.finger.print.error')); } if (!empty($config['max_filesize']) && $file['size'] > $config['max_filesize'] * 1024 * 1024) { return $this->format(self::API_FAIL, $huiLang->_('cdn.upload.files.maxsize.error', $config['max_filesize'])); } } return $this->format(self::API_SUCCESS, 'ok'); } catch (Exception $e) { return $this->format(self::API_FAIL, $e->getMessage()); } }
/** * 执行期末绑定 */ protected function initShutCall() { $this->shutCall = \HuiLib\Runtime\ShutCall::create(); Front::getInstance()->setShutCall($this->shutCall); }
/** * 创建一个Session适配器 * * 支持redis、memcache、dbtable等三种适配器 */ public static function create() { $configInstance = Front::getInstance()->getAppConfig(); $config = $configInstance->getByKey('session'); if (empty($config['adapter']) || empty($config['driver'])) { throw new \HuiLib\Error\Exception('Session adapter & driver can not be empty'); } $driverConfig = $configInstance->getByKey($config['driver']); if (empty($driverConfig)) { throw new \HuiLib\Error\Exception('Session driver config can not be empty'); } //设置session键前缀 if (!empty($config['prefix'])) { self::$prefix = $config['prefix']; } //权限验证名称 $authCookie = $configInstance->getByKey('session.auth'); if (!empty($authCookie)) { self::$authCookieName = $authCookie; } switch ($config['adapter']) { case 'memcache': $driver = new \HuiLib\Session\Storage\Memcache($driverConfig); break; case 'redis': $driver = new \HuiLib\Session\Storage\Redis($driverConfig); break; } //保存session配置信息 $driver->config = $config; //设置后端生命期 $driver->setLife($configInstance->getByKey('session.authLife')); //注册Session处理函数 session_set_save_handler($driver, TRUE); session_start(); //Session开启后事件调用 if ($driver->manager->getModel()) { $driver->manager->getModel()->onSessionStart(); } return $driver; }
/** * 加载控制器 * * 路由原理: * 1、以Controller为基础,不再支持任意指定一级目录;默认是IndexController * 2、Controller不存在的,再执行一级目录路由 * 3、另外支持二级域名、拓展独立域名 * 4、Bin模式需要将参数组合成scriptUrl * * @throws \Exception */ protected function loadController() { try { //默认到controller级 $controllerClass = 'Controller' . NAME_SEP . self::mapRouteSegToClass($this->package) . NAME_SEP . self::mapRouteSegToClass($this->controller); try { $this->controllerInstance = new $controllerClass(); } catch (AutoLoaderException $e) { throw new RouteControllerException('Controller class not exists.'); } //大小写规范问题 if (strtolower($this->package) != $this->getPackageRouteSeg() || strtolower($this->controller) != $this->getControllerRouteSeg() || get_class($this->controllerInstance) != $controllerClass) { //强力规范url exit("Bad url route package or controller format."); } Front::getInstance()->setController($this->controllerInstance); } catch (RouteControllerException $exception) { $controllerRoute = new \HuiLib\App\Route\Controller(); Front::getInstance()->setControllerRoute($controllerRoute); //Controller路由处理 /topic/2 $controllerRoute->route(); } }
private static function staticCreate($adapterName) { $configInstance = Front::getInstance()->getAppConfig(); $adapterConfig = $configInstance->getByKey($adapterName); if (empty($adapterConfig)) { throw new \HuiLib\Error\Exception($adapterName . ' adapter config has not set.'); } return self::create($adapterConfig); }
/** * 获取系统默认翻译实例 * * 直接调用创建默认实例 */ public static function getDefault(\HuiLib\Config\ConfigBase $configInstance = NULL, $lang = NULL) { if (self::$defaultInstance !== NULL) { return self::$defaultInstance; } if ($configInstance === NULL) { $configInstance = Front::getInstance()->getAppConfig(); } $config = $configInstance->getByKey('lang'); if (empty($config)) { throw new \HuiLib\Error\Exception('Lang default adapter has not set.'); } self::$defaultInstance = self::create($config, $lang); return self::$defaultInstance; }
/** * 获取库翻译实例 */ protected static function getHuiLang() { return Front::getInstance()->getHuiLang(); }
/** * 生成一个头像储存路径 * * 需要将size替换为相应规格号 */ protected function getAvatarPath($meta) { if (empty($meta['size']) || empty($meta['type']) || empty($meta['name']) || empty($meta['uid'])) { throw new Exception(Front::getInstance()->getHuiLang()->_('cdn.upload.files.error')); } $uid = $meta['uid']; $config = $this->getConfig(); $type = Param::post('type', Param::TYPE_STRING); //替换为10位,刚好10亿 1000,000,000 $uidStr = sprintf("%010d", $uid); $filePath = $config['save_path'] . $type . SEP . substr($uidStr, 0, 4) . SEP . substr($uidStr, 4, 3) . SEP . substr($uidStr, 7, 3) . SEP; //创建目录 if (!is_dir($filePath)) { mkdir($filePath, 0777, TRUE); } $ext = $this->getExt($meta['name']); $file = $filePath . '{size}' . $ext; $result = array(); $result['file'] = $file; $result['url'] = str_ireplace(SEP, URL_SEP, str_ireplace($config['save_path'], '', $file)); return $result; }
/** * 获取翻译实例 */ protected function getLang() { return Front::getInstance()->getLang(); }
/** * 获取引导类实例 * @return \HuiLib\Bootstrap */ public static function create() { $instance = new self(); Front::getInstance()->setBootstrap($instance); return $instance; }
/** * 设置数据库配置 * @param array $config */ protected static function initConfig() { if (self::$config === NULL) { $configInstance = Front::getInstance()->getAppConfig(); self::$config = $configInstance->getByKey('db'); } }
/** * 解析应用配置ini文件 * @throws \HuiLib\Error\Exception */ private function parse() { if (!is_file($this->filePath)) { throw new \HuiLib\Error\Exception("Config file: {$this->filePath} Not exists!"); } $this->configSource = parse_ini_file($this->filePath, self::PARSE_SECTION); if (!is_array($this->configSource)) { throw new \HuiLib\Error\Exception("Config ini file parsed Exception!"); } //检测是否存在服务器环境标签 $allowEnvTag = Front::getInstance()->getBootstrap()->getAllowEnv(); $existSection = FALSE; foreach ($allowEnvTag as $envTag) { if (isset($this->configSource[$envTag])) { $existSection = TRUE; } } /** * 解析块元素 * * 1、存在[production]等标签,根据继承合并块 * 2、不包括环境标签的直接解析数组 */ if ($existSection) { $this->configFinal = $this->mergeSection(); if (isset($this->configFinal[APP_ENV])) { $this->configEnv =& $this->configFinal[APP_ENV]; } else { $this->configEnv = array(); } } else { $this->configFinal = $this->getSettingFromBlock($this->configSource); $this->configEnv =& $this->configFinal; } //缓存到缓存服务器 $cache = array(); $cache['data'] = $this->configFinal; $cache['section'] = $existSection; $cache['stamp'] = filemtime($this->filePath); $this->lastUpate = $cache['stamp']; $this->cacheAdapter->add($this->getCacheKey(), $cache); }
/** * 初始化网站配置实例 */ protected static function getSiteConfig() { return Front::getInstance()->getSiteConfig(); }