Application.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. <?php
  2. namespace Qii;
  3. class Application
  4. {
  5. /**
  6. * 存储网站配置文件内容
  7. *
  8. * @var array $config 配置内容
  9. */
  10. protected static $config = [];
  11. /**
  12. * @var object $logerWriter 写日志工具
  13. */
  14. public $logerWriter = null;
  15. /**
  16. * @var string $workspace 工作目录
  17. */
  18. private static $workspace = './';/**
  19. * @var string $env 环境变量
  20. */
  21. public static $env = 'product';
  22. /**
  23. * @var array $paths 网站使用的路径
  24. */
  25. public static $paths = array('configure', 'controller', 'model', 'view', 'plugins', 'tmp');
  26. /**
  27. * Qii\Request\Url
  28. */
  29. public $request;
  30. public function __construct()
  31. {
  32. $this->helper = \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\Autoloader\Helper');
  33. }
  34. /**
  35. * 初始化本实例对象
  36. *
  37. * @return object
  38. */
  39. public static function getInstance()
  40. {
  41. return \Qii\Autoloader\Factory::getInstance('\Qii\Application');
  42. }
  43. /**
  44. * 设置网站运行环境
  45. *
  46. * @param string $env 网站环境
  47. * @return $this
  48. */
  49. public function setEnv($env)
  50. {
  51. self::$env = $env;
  52. return $this;
  53. }
  54. /**
  55. * 设置缓存文件路径
  56. * @param string $path 缓存路径
  57. */
  58. public function setCachePath($path)
  59. {
  60. \Qii\Config\Register::set(\Qii\Config\Consts::APP_CACHE_PATH, $this->getCachePath($path));
  61. return $this;
  62. }
  63. /**
  64. * 保存网站的配置文件
  65. *
  66. * @param $iniFile
  67. */
  68. public function setAppIniFile($iniFile)
  69. {
  70. \Qii\Config\Register::set(\Qii\Config\Consts::APP_INI_FILE, $iniFile);
  71. return $this;
  72. }
  73. /**
  74. * 设置网站的工作目录,可以通过此方法将网站的重要文件指向到其他目录
  75. *
  76. * @param string $workspace 工作目录
  77. * @return $this
  78. */
  79. public function setWorkspace($workspace = './')
  80. {
  81. //此处转换成真实路径,防止workspace中引入的文件出错
  82. if (!is_dir($workspace)) {
  83. throw new \Qii\Exceptions\FolderDoesNotExist(\Qii::i(1045, $workspace), __LINE__);
  84. }
  85. $workspace = \Qii\Autoloader\Psr4::getInstance()->realpath($workspace);
  86. \Qii\Autoloader\Psr4::getInstance()->removeNamespace('workspace', self::$workspace);
  87. //如果配置了使用namespace就走namespace
  88. self::$workspace = $workspace;
  89. \Qii\Autoloader\Psr4::getInstance()->addNamespace('workspace', $workspace, true);
  90. foreach (self::$paths AS $path) {
  91. \Qii\Autoloader\Psr4::getInstance()->addNamespace($path, $workspace . '\\' . $path);
  92. }
  93. return $this;
  94. }
  95. /**
  96. * 获取指定路径的缓存绝对路径
  97. * @param string $path 路径
  98. * @return string 绝对路径
  99. */
  100. public function getCachePath($path)
  101. {
  102. if (self::$workspace != '') return self::$workspace . DS . $path;
  103. $dir = '';
  104. $workspace = \Qii\Autoloader\Psr4::getInstance()->getNamespace('workspace');
  105. foreach ($workspace AS $dir) {
  106. if (is_dir($dir)) $dir = $dir;
  107. }
  108. return $dir . DS . $path;
  109. }
  110. /**
  111. * 获取网站运行环境
  112. *
  113. * @return string
  114. */
  115. public function getEnv()
  116. {
  117. return self::$env;
  118. }
  119. /**
  120. * 获取当前工作目录
  121. */
  122. public function getWorkspace()
  123. {
  124. return self::$workspace;
  125. }
  126. /**
  127. * 获取网站的配置文件
  128. * @return Mix
  129. */
  130. public function getAppIniFile()
  131. {
  132. return \Qii\Config\Register::get(\Qii\Config\Consts::APP_INI_FILE);
  133. return $this;
  134. }
  135. /**
  136. * 设置网站配置文件
  137. * @param string $ini 配置文件路径
  138. * @param string $env 环境
  139. *
  140. */
  141. public function setAppConfigure($ini, $env = '')
  142. {
  143. if ($env == '') $env = $this->getEnv();
  144. $ini = \Qii\Autoloader\Psr4::getInstance()->getFileByPrefix($ini);
  145. $this->setAppIniFile($ini);
  146. if (!\Qii\Config\Register::setAppConfigure(
  147. $ini,
  148. $env
  149. )
  150. ) throw new \Qii\Exceptions\FileNotFound(\Qii::i(1405, $ini), __LINE__);
  151. //载入request方法
  152. $this->request = \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\Request\Http');
  153. \Qii\Config\Setting::getInstance()->setDefaultTimeZone();
  154. \Qii\Config\Setting::getInstance()->setDefaultControllerAction();
  155. \Qii\Config\Setting::getInstance()->setDefaultNamespace();
  156. \Qii\Config\Setting::getInstance()->setDefaultLanguage();
  157. return $this;
  158. }
  159. /**
  160. * 合并ini文件生成的数组
  161. * @param String $iniFile ini文件名
  162. * @param Array $array
  163. */
  164. public function mergeAppConfigure($iniFile, $array)
  165. {
  166. if (!is_array($array)) return;
  167. \Qii\Config\Register::mergeAppConfigure($iniFile, $array);
  168. return $this;
  169. }
  170. /**
  171. * 覆盖/添加ini文件的key对应的值
  172. * @param String $iniFile ini文件名
  173. * @param String $key
  174. * @param String $val
  175. */
  176. public function rewriteAppConfigure($iniFile, $key, $val)
  177. {
  178. \Qii\Config\Register::rewriteConfig($iniFile, $key, $val);
  179. return $this;
  180. }
  181. /**
  182. * 设置指定的前缀是否使用命名空间
  183. * @param string $prefix 前缀
  184. * @param bool $useNamespace 是否使用
  185. * @return $this
  186. */
  187. public function setUseNamespace($prefix, $useNamespace = true)
  188. {
  189. \Qii\Autoloader\Psr4::getInstance()->setUseNamespace($prefix, $useNamespace);
  190. return $this;
  191. }
  192. /**
  193. * 添加命名空间对应的网站目录
  194. * @param string $prefix 前缀
  195. * @param string $baseDir 对应的路径
  196. * @param bool $prepend 是否追加
  197. * @return $this
  198. */
  199. public function addNamespace($prefix, $baseDir, $prepend = false)
  200. {
  201. if (!is_dir($baseDir)) {
  202. throw new \Qii\Exceptions\FolderDoesNotExist(\Qii::i(1009, $baseDir), __LINE__);
  203. }
  204. $baseDir = \Qii\Autoloader\Psr4::getInstance()->realpath($baseDir);
  205. \Qii\Autoloader\Psr4::getInstance()->addNamespace($prefix, $baseDir, $prepend);
  206. return $this;
  207. }
  208. /**
  209. * 设置启动前执行的方法
  210. *
  211. * @return $this
  212. * @throws Exception
  213. */
  214. public function setBootstrap()
  215. {
  216. \Qii\Autoloader\Psr4::getInstance()->loadFileByClass('Bootstrap');
  217. if (!class_exists('Bootstrap', false)) throw new \Qii\Exceptions\ClassNotFound(\Qii::i(1405, 'Bootstrap'), __LINE__);;
  218. $bootstrap = \Qii\Autoloader\Psr4::getInstance()->instance('Bootstrap');
  219. if (!$bootstrap instanceof \Qii\Base\Bootstrap) {
  220. throw new \Qii\Exceptions\ClassInstanceof(Qii::i(1107, 'Bootstrap', 'Qii\Bootstrap'), __LINE__);;
  221. }
  222. $refectionClass = new \ReflectionClass('Bootstrap');
  223. $methods = $refectionClass->getMethods();
  224. //自动执行以init开头的公共方法
  225. foreach ($methods as $method) {
  226. $name = $method->getName();
  227. if (substr($name, 0, 4) == 'init' && $method->isPublic()) $bootstrap->$name();
  228. }
  229. return $this;
  230. }
  231. /**
  232. * 设置写loger的类
  233. *
  234. * @param LogerWriter $logerCls 日志记录类
  235. */
  236. public function setLoger($logerCls)
  237. {
  238. /*
  239. if (!class_exists($logerCls, false)) {
  240. throw new \Qii_Exceptions_ClassNotFound(Qii::i(1405, $logerCls), __LINE__);
  241. }*/
  242. $this->logerWriter = \Qii\Autoloader\Instance::instance(
  243. '\Qii\Loger\Instance',
  244. \Qii\Autoloader\Instance::instance($logerCls)
  245. );
  246. return $this;
  247. }
  248. /**
  249. * 设置数据库使用的文件
  250. *
  251. * @param $iniFile
  252. * @throws \Qii_Exceptions_Overwrite
  253. */
  254. public function setDBIniFile($iniFile)
  255. {
  256. \Qii\Config\Register::set(\Qii\Config\Consts::APP_DB, $iniFile);
  257. }
  258. /**
  259. * 获取当前数据库文件
  260. *
  261. * @return \Qii_Mix
  262. * @throws \Qii_Exceptions_Variable
  263. */
  264. public function getDBIniFile()
  265. {
  266. return \Qii\Config\Register::get(\Qii\Config\Consts::APP_DB);
  267. }
  268. /**
  269. * 设置数据库配置文件
  270. * @param string $ini 配置文件路径
  271. * @param string $env 环境
  272. */
  273. public function setDB($ini, $env = '')
  274. {
  275. if ($env == '') $env = $this->getEnv();
  276. $this->setDBIniFile($ini);
  277. if (!\Qii\Config\Register::setAppConfigure(
  278. \Qii\Autoloader\Psr4::getInstance()->getFileByPrefix($ini),
  279. $env
  280. )
  281. ) {
  282. throw new \Qii\Exceptions\FileNotFound(\Qii::i(1405, $ini), __LINE__);
  283. }
  284. return $this;
  285. }
  286. /**
  287. * 设置路由规则
  288. *
  289. * @param string $router 路由配置文件位置
  290. * @return $this
  291. */
  292. public function setRouter($router)
  293. {
  294. \Qii\Config\Register::set(
  295. \Qii\Config\Consts::APP_SITE_ROUTER,
  296. \Qii\Autoloader\Import::includes(
  297. \Qii\Autoloader\Psr4::realpath(\Qii\Autoloader\Psr4::getInstance()->getFileByPrefix($router)
  298. )
  299. )
  300. );
  301. //载入rewrite规则后重写request
  302. $rewrite = \Qii\Autoloader\Psr4::loadStatic(
  303. '\Qii\Route\Parse',
  304. 'get',
  305. $this->request->controller,
  306. $this->request->action,
  307. $this->request->url->get(2)
  308. );
  309. $rewrite['controller'] = $rewrite['controller'] ? $rewrite['controller'] : $this->request->defaultController();
  310. $rewrite['action'] = $rewrite['action'] ? $rewrite['action'] : $this->request->defaultAction();
  311. //是否已经rewrite,如果和url中的不一样就是已经rewrite
  312. if ($this->request->controller != $rewrite['controller'] || $this->request->action != $rewrite['action']) {
  313. $this->request->setRouted(true);
  314. }
  315. $this->request->controllerName($rewrite['controller']);
  316. $this->request->setActionName($rewrite['action']);
  317. return $this;
  318. }
  319. /**
  320. * sprintf 格式化语言错误信息内容
  321. *
  322. * Qii::e($message, $argv1, $argv2, ..., $line);
  323. * $message = sprintf($message, $argv1, $argv2, ...);
  324. * throw new \Qii\Exceptions\Error($message, $line);
  325. */
  326. public function showError()
  327. {
  328. return call_user_func_array(array('\Qii\Exceptions\Errors', 'e'), func_get_args());
  329. }
  330. public function run()
  331. {
  332. $this->helper->load(self::$workspace);
  333. $this->dispatcher = \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\Base\Dispatcher');
  334. if (!$this->dispatcher instanceof \Qii\Base\Dispatcher) {
  335. throw new \Exception('Dispatcher must instance of Qii\Base\Dispatcher', __LINE__);
  336. }
  337. //如果设置了host的话,看host对应的controller路径
  338. $hosts = $this->appConfigure('hosts');
  339. if (count($hosts) > 0) {
  340. foreach ($hosts AS $host) {
  341. if ($host['domain'] == $this->request->host) {
  342. \Qii\Config\Register::set(
  343. \Qii\Config\Consts::APP_DEFAULT_CONTROLLER_PREFIX,
  344. ($host['path'] ? $host['path'] : $host['domain'])
  345. );
  346. break;
  347. }
  348. }
  349. }
  350. $this->request->setDispatcher($this->dispatcher);
  351. //rewrite规则
  352. $this->dispatcher->setRequest($this->request);
  353. $this->dispatcher->dispatch();
  354. $this->request->setDispatched(true);
  355. return $this;
  356. }
  357. }