helper = Psr4::getInstance()->loadClass('\Qii\Autoloader\Helper'); } /** * 初始化本实例对象 * * @return object */ public static function getInstance() { $args = func_get_args(); if (count($args) > 0) { $className = array_shift($args); return Psr4::getInstance($className); } return Factory::getInstance('\Qii\Application'); } /** * 设置网站运行环境 * * @param string $env 网站环境 * @return $this */ public function setEnv($env) { self::$env = $env; return $this; } /** * 设置缓存文件路径 * @param string $path 缓存路径 */ public function setCachePath($path) { Register::set(Consts::APP_CACHE_PATH, $this->getCachePath($path)); return $this; } /** * 保存网站的配置文件 * * @param $iniFile */ public function setAppIniFile($iniFile) { Register::set(Consts::APP_INI_FILE, $iniFile); return $this; } /** * 设置网站的工作目录,可以通过此方法将网站的重要文件指向到其他目录 * * @param string $workspace 工作目录 * @return $this */ public function setWorkspace($workspace = './') { //此处转换成真实路径,防止workspace中引入的文件出错 if (!is_dir($workspace)) { throw new FolderDoesNotExist(\Qii::i(1045, $workspace), __LINE__); } $workspace = Psr4::getInstance()->realpath($workspace); Psr4::getInstance()->removeNamespace('workspace', self::$workspace); //如果配置了使用namespace就走namespace self::$workspace = $workspace; Psr4::getInstance()->addNamespace('workspace', $workspace, true); foreach (self::$paths AS $path) { Psr4::getInstance()->addNamespace($path, $workspace . '\\' . $path); } return $this; } /** * 获取指定路径的缓存绝对路径 * @param string $path 路径 * @return string 绝对路径 */ public function getCachePath($path) { if (self::$workspace != '') return self::$workspace . DS . $path; $dir = ''; $workspace = Psr4::getInstance()->getNamespace('workspace'); foreach ($workspace AS $dir) { if (is_dir($dir)) $dir = $dir; } return $dir . DS . $path; } /** * 获取网站运行环境 * * @return string */ public function getEnv() { return self::$env; } /** * 获取当前工作目录 */ public function getWorkspace() { return self::$workspace; } /** * 获取网站的配置文件 * @return Config\Mix */ public function getAppIniFile() { return Register::get(Consts::APP_INI_FILE); } /** * 设置网站配置文件 * @param string $ini 配置文件路径 * @param string $env 环境 * @return $this * @throws ClassNotFound */ public function setAppConfigure($ini, $env = '') { if ($env == '') $env = $this->getEnv(); $ini = Psr4::getInstance()->getFileByPrefix($ini); $this->setAppIniFile($ini); if (!Register::setAppConfigure($ini, $env)) throw new FileNotFound($ini, 404); //载入request方法 $this->request = $this->getRequest(); $this->dispatcher = $this->getDispatcher(); if (!$this->dispatcher instanceof Dispatcher) { throw new \Exception('Dispatcher must instance of Qii\Base\Dispatcher', __LINE__); } Setting::getInstance()->setDefaultTimeZone(); Setting::getInstance()->setDefaultControllerAction(); Setting::getInstance()->setDefaultNamespace(); Setting::getInstance()->setDefaultLanguage(); $this->helper->load(self::$workspace); return $this; } /** * 合并ini文件生成的数组 * @param String $iniFile ini文件名 * @param Array $array * @return $this */ public function mergeAppConfigure($iniFile, $array) { if (!is_array($array)) return; Register::mergeAppConfigure($iniFile, $array); return $this; } /** * 覆盖/添加ini文件的key对应的值 * @param string $iniFile ini文件名 * @param string $key * @param string $val * @return $this */ public function rewriteAppConfigure($iniFile, $key, $val) { Register::rewriteConfig($iniFile, $key, $val); return $this; } /** * 设置指定的前缀是否使用命名空间 * @param string $prefix 前缀 * @param bool $useNamespace 是否使用 * @return $this */ public function setUseNamespace($prefix, $useNamespace = true) { Psr4::getInstance()->setUseNamespace($prefix, $useNamespace); return $this; } /** * 添加命名空间对应的网站目录 * @param string $prefix 前缀 * @param string $baseDir 对应的路径 * @param bool $prepend 是否追加 * @return $this */ public function addNamespace($prefix, $baseDir, $prepend = false) { if (!is_dir($baseDir)) { throw new FolderDoesNotExist(\Qii::i(1009, $baseDir), __LINE__); } $baseDir = Psr4::getInstance()->realpath($baseDir); Psr4::getInstance()->addNamespace($prefix, $baseDir, $prepend); return $this; } /** * 设置启动前执行的方法 * * @return $this * @throws Exception */ public function setBootstrap() { Psr4::getInstance()->loadFileByClass('Bootstrap'); if (!class_exists('Bootstrap', false)) throw new ClassNotFound(\Qii::i(1405, 'Bootstrap'), __LINE__);; $bootstrap = Psr4::getInstance()->instance('Bootstrap'); if (!$bootstrap instanceof Bootstrap) { throw new ClassInstanceof(Qii::i(1107, 'Bootstrap', 'Qii\Bootstrap'), __LINE__);; } $refectionClass = new \ReflectionClass('Bootstrap'); $methods = $refectionClass->getMethods(); //自动执行以init开头的公共方法 foreach ($methods as $method) { $name = $method->getName(); if (substr($name, 0, 4) == 'init' && $method->isPublic()) $bootstrap->$name(); } return $this; } /** * 全局 Middleware * @param array $middleware * @return void */ public function setGlobalMiddleware($middleware) { if (!is_array($middleware)) { return $this; } $this->middleware = array_merge($this->middleware, $middleware); return $this; } /** * 实例化request并返回 * * @return mixed * @throws ClassNotFound */ public function getRequest() { if ($this->request !== null) { return $this->request; } return Psr4::getInstance()->loadClass('\Qii\Request\Http'); } /** * Set Dispatcher * @return void * @throws ClassNotFound */ public function getDispatcher() { if ($this->dispatcher !== null) { return $this->dispatcher; } return Psr4::getInstance()->loadClass('\Qii\Base\Dispatcher'); } /** * 设置写loger的类 * * @param LoggerWriter $loggerCls 日志记录类 * @return $this */ public function setLogger($loggerCls) { $this->loggerWriter = Instance::instance( '\Qii\Logger\Instance', Instance::instance($loggerCls) ); return $this; } /** * 设置缓存 * * @param string $engine 缓存方法 * @param array $policy 缓存策略 */ public function setCache($engine = '', $policy = array()) { $engine = $engine == '' ? \Qii::appConfigure('cache') : $engine; $basicPolicy = array( 'servers' => $this->getCachePolicy($engine), ); if ($basicPolicy['servers']) { $policy = array_merge($basicPolicy, $policy); } $loader = new \Qii\Cache\Loader($engine); return $loader->initialization($policy); } /** * 获取缓存的策略 * @param String $cache 缓存的内容 * @return multitype:multitype:Ambigous <> */ public function getCachePolicy($cache) { $data = array(); if (!$cache) return $data; $cacheInfo = Register::getAppConfigure(Register::get(Consts::APP_INI_FILE), $cache); if (!$cacheInfo) return $data; $servers = explode(";", $cacheInfo['servers']); $ports = explode(";", $cacheInfo['ports']); $password = explode(';', (isset($cacheInfo['password']) ? $cacheInfo['password'] : '')); for ($i = 0; $i < count($servers); $i++) { $data[] = array('host' => $servers[$i], 'port' => $ports[$i], 'password' => $password[$i]); } return $data; } /** * 设置view * * @param string $engine * @param array $policy * @return mixed */ public function setView($engine = 'smarty', $policy = array()) { $viewConfigure = \Qii::appConfigure('view'); //如果之前实例化过相同的就不再实例化 if (!$engine) $engine = $viewConfigure['engine']; $policy = (array)$policy; if (!$policy) { $policy = array_merge($policy, $viewConfigure[$engine]); } $viewEngine = Psr4::getInstance()->loadClass('\Qii\View\Loader'); $viewEngine->setView($engine, $policy); return $viewEngine; } /** * 设置数据库使用的文件 * * @param $iniFile * @throws \Qii\Exceptions\Overwrite */ public function setDBIniFile($iniFile) { Register::set(Consts::APP_DB, $iniFile); } /** * 获取当前数据库文件 * * @return \Qii\Mix * @throws \Qii\Exceptions\Variable */ public function getDBIniFile() { return Register::get(Consts::APP_DB); } /** * 设置数据库配置文件 * @param string $ini 配置文件路径 * @param string $env 环境 */ public function setDB($ini, $env = '') { if ($env == '') $env = $this->getEnv(); $this->setDBIniFile($ini); if (!Register::setAppConfigure( Psr4::getInstance()->getFileByPrefix($ini), $env) ) { throw new FileNotFound($ini, 404); } return $this; } /** * @param string $path 从指定路径加载路由 * * @return $this */ public function loadRouteFromPath($path) { Import::requireByDir($path); return $this; } /** * 设置路由规则 * * @param string $router 路由配置文件位置 * @return mixed */ public function setRouter($router) { $router = Import::includes(Psr4::realpath(Psr4::getInstance()->getFileByPrefix($router))); if(is_array($router)) { $this->router = array_merge($this->router, $router); } Register::set( Consts::APP_SITE_ROUTER, $this->router ); return $this; } /** * sprintf 格式化语言错误信息内容 * * Qii::e($message, $argv1, $argv2, ..., $line); * $message = sprintf($message, $argv1, $argv2, ...); * throw new \Qii\Exceptions\Error($message, $line); */ public function showError() { return call_user_func_array(array('\Qii\Exceptions\Errors', 'e'), func_get_args()); } /** * 执行 * @return $this * @throws \Exception */ public function run() { //全局middleware $reserve = array_unique(array_reverse($this->middleware)); $next = array_reduce($reserve,function ($carry, $item){ return function () use ($carry, $item){ return _loadClass($item)->handle(\Qii::getInstance()->request, $carry); }; }, function(){ return true; })(); if ($next === false) { return $this; } //route middleware $next = call_user_func( array_reduce(['Route'], function($carry, $item){ return function () use ($carry, $item){ return \Qii::getInstance("Qii\Base\\". $item)->match($this->request, $carry); }; }, function(){ //载入rewrite规则后重写request $rewrite = Psr4::loadStatic( '\Qii\Router\Parse', 'get', Url::getPathInfo(), $this->request->controller, $this->request->action, $this->request->url->get(2) ); $rewrite['controller'] = isset($rewrite['controller']) && $rewrite['controller'] ? $rewrite['controller'] : $this->request->defaultController(); $rewrite['action'] = isset($rewrite['action']) && $rewrite['action'] ? $rewrite['action'] : $this->request->defaultAction(); //是否已经rewrite,如果和url中的不一样就是已经rewrite if ($this->request->controller != $rewrite['controller'] || $this->request->action != $rewrite['action']) { $this->request->setRouted(true); } $this->request->setControllerName($rewrite['controller']); $this->request->setActionName($rewrite['action']); return true; }) ); if ($next === false) { return $this; } //如果app.ini中设置了host的话,看host对应的controller路径 $hosts = $this->appConfigure('hosts'); if (!empty($hosts) && is_array($hosts) && count($hosts) > 0) { foreach ($hosts AS $host) { if ($host['domain'] == $this->request->host) { Register::set( Consts::APP_DEFAULT_CONTROLLER_PREFIX, (isset($host['path']) && $host['path'] ? $host['path'] : $host['domain']) ); break; } } } $this->request->setDispatcher($this->dispatcher); //rewrite规则 $this->dispatcher->setRequest($this->request); $this->dispatcher->dispatch(); $this->request->setDispatched(true); return $this; } }