Qii.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <?php
  2. use \Qii\Application;
  3. use \Qii\Autoloader\Factory;
  4. use Qii\Autoloader\Import;
  5. use \Qii\Autoloader\Psr4;
  6. use \Qii\Config\Register;
  7. /**
  8. * Qii 框架基本库所在路径
  9. */
  10. define('QII_DIR', dirname(__FILE__));
  11. /**
  12. * DIRECTORY_SEPARATOR 的简写
  13. */
  14. define('DS', DIRECTORY_SEPARATOR);
  15. /**
  16. * 定义包含的路径分隔符
  17. */
  18. define('PS', PATH_SEPARATOR);
  19. /**
  20. * 定义操作系统类型
  21. */
  22. define('OS', strtoupper(substr(PHP_OS, 0, 3)));
  23. define('IS_CLI', php_sapi_name() == 'cli' ? true : false);
  24. if (IS_CLI) {
  25. $args = isset($argv) && is_array($argv) && count($argv) > 0 ? $argv : array();
  26. if(count($args) == 0 && isset($_SERVER['argv'])
  27. && is_array($_SERVER['argv']) && count($_SERVER['argv']) > 0) {
  28. $args = $_SERVER['argv'];
  29. }
  30. $cliAgs = QiiHandleCliArgs($args);
  31. $_SERVER['__CLI_ARGS'] = $cliAgs;
  32. $_SERVER['REQUEST_URI'] = $cliAgs[1] . ($cliAgs[3] ? '?'. $cliAgs[3] : '');
  33. $_SERVER['QUERY_STRING'] = $cliAgs[3];
  34. $_SERVER['SCRIPT_NAME'] = $cliAgs[0];
  35. $_GET = $cliAgs[2];
  36. $_POST = $cliAgs[2];
  37. define('PATH_INFO', $cliAgs[1]);
  38. } else {
  39. define('PATH_INFO', isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '');
  40. }
  41. /**
  42. * EOL 和 SPACE
  43. */
  44. define('QII_EOL', IS_CLI ? PHP_EOL : '<br />');
  45. define('QII_SPACE', IS_CLI ? ' ' : '&nbsp;');
  46. require QII_DIR . DS . 'Autoloader' . DS . 'Import.php';
  47. Import::setFileLoaded(QII_DIR . DS . 'Autoloader' . DS . 'Import.php');
  48. Import::requires(
  49. array(QII_DIR . DS . 'Config' . DS . 'Consts.php',
  50. QII_DIR . DS . 'Functions' . DS . 'Funcs.php',
  51. QII_DIR . DS . 'Autoloader' . DS . 'Factory.php',
  52. QII_DIR . DS . 'Application.php',
  53. QII_DIR . DS . 'Autoloader' . DS . 'Psr4.php',
  54. QII_DIR . DS . 'Config' . DS . 'Arrays.php',
  55. )
  56. );
  57. function QiiHandleCliArgs($parameter) {
  58. $fileName = array_shift($parameter);
  59. $uri = array_shift($parameter);
  60. if(substr($uri, 0, 1) != '/') {
  61. $uri = "/". $uri;
  62. }
  63. //解析parameter
  64. $params = array();
  65. $query = [];
  66. foreach ($parameter as $value) {
  67. preg_match("/\{(?P<name>(.*?))(\=|\:)(?P<value>(.*).+)\}/", $value, $matches);
  68. if($matches && isset($matches['name'])) {
  69. $params[$matches['name']] = $matches['value'];
  70. $query[] = $matches['name'] .'='. urlencode($matches['value']);
  71. }else {
  72. preg_match("/(?P<name>(.*?))(\=|\:)(?P<value>(.*).+)/", $value, $matches);
  73. if($matches && isset($matches['name'])) {
  74. $params[$matches['name']] = $matches['value'];
  75. $query[] = $matches['name'] . '=' . urlencode($matches['value']);
  76. }else{
  77. $parameter[$value] = '';
  78. $query[] = $value .'=';
  79. }
  80. }
  81. }
  82. return array($fileName, $uri, $params, join("&", $query));
  83. }
  84. class Qii extends Application
  85. {
  86. public function __construct()
  87. {
  88. parent::__construct();
  89. }
  90. /**
  91. * Instance func
  92. *
  93. **/
  94. public static function getInstance()
  95. {
  96. if (func_num_args() > 0) {
  97. $args = func_get_args();
  98. return call_user_func_array(array('\Qii\Autoloader\Factory', 'getInstance'), $args);
  99. }
  100. return Factory::getInstance('\Qii');
  101. }
  102. /**
  103. * 设置private 属性
  104. *
  105. * @param String $name
  106. * @param Mix $value
  107. */
  108. public static function setPrivate($name, $value)
  109. {
  110. return Psr4::getInstance()->loadClass('\Qii\Config\Arrays')->setPrivate($name, $value);
  111. }
  112. /**
  113. * 获取private属性
  114. *
  115. * @param String $name
  116. * @param String $key
  117. * @return Mix
  118. */
  119. public static function getPrivate($name, $key = '')
  120. {
  121. $private = Psr4::getInstance()->loadClass('\Qii\Config\Arrays')->get($name);
  122. if (preg_match('/^\s*$/', $key)) {
  123. return $private;
  124. }
  125. if (isset($private[$key])) return $private[$key];
  126. }
  127. /**
  128. * 获取语言包内容指定的内容
  129. *
  130. * @return mixed
  131. */
  132. public static function i()
  133. {
  134. return call_user_func_array(array(
  135. Psr4::getInstance()->loadClass('\Qii\Language\Loader'), 'i'),
  136. func_get_args()
  137. );
  138. }
  139. /**
  140. * 错误设置,如果满足给定的条件就直接返回false,否则在设置了错误页面的情况下返回true
  141. * 如果出错后要终止的话,需要自行处理,此方法不错停止不执行
  142. *
  143. * @param Bool $condition
  144. * @param int $line 出错的行数,这样以便轻松定位错误
  145. * @param String $msg
  146. * @param Int|String $code
  147. * @return Bool
  148. */
  149. public static function setError($condition, $line = 0, $code = 0, $args = null, $msg = '')
  150. {
  151. return call_user_func_array(array('\Qii\Exceptions\Error', 'setError'), func_get_args());
  152. }
  153. /**
  154. * 抛出异常
  155. *
  156. * @return mixed
  157. */
  158. public static function e()
  159. {
  160. return call_user_func_array(array('\Qii\Exceptions\Errors', 'e'), func_get_args());
  161. }
  162. /**
  163. * 返回当前app的配置
  164. * @param string $key 如果需要返回单独的某一个key就指定一下这个值
  165. * @return mixed
  166. */
  167. public static function appConfigure($key = null)
  168. {
  169. return Register::getAppConfigure(\Qii::getInstance()->getAppIniFile(), $key);
  170. }
  171. /**
  172. * 当调用Qii不存在的方法的时候,试图通过Autoload去加载对应的类
  173. * 示例:
  174. * \Qii::getInstance()->Qii_Autoloader_Psr4('instance', 'Model\User');
  175. * 此方法将调用:Qii_Autoloader_Psr4->instance('Model\User');
  176. */
  177. public function __call($className, $args)
  178. {
  179. return call_user_func_array(array(Psr4::getInstance(), 'loadClass'), func_get_args());
  180. }
  181. /**
  182. * 当调用不存在的静态方法的时候会试图执行对应的类和静态方法
  183. * 斜线将会转换成下划线
  184. * 示例:
  185. * \Qii::Qii_Autoloader_Psr4('getInstance')
  186. * 此方法将调用:\Qii\Autoloader\Psr4::getInstance静态方法
  187. * Qii::InstanceApp("App");
  188. * 此方法将调用:InstanceApp::App()静态方法
  189. */
  190. public static function __callStatic($className, $args)
  191. {
  192. $method = array_shift($args);
  193. $className = Psr4::getInstance()->getClassName($className);
  194. return call_user_func_array($className . '::' . $method, $args);
  195. }
  196. }
  197. if (!function_exists('catch_fatal_error')) {
  198. function catch_fatal_error()
  199. {
  200. // Getting Last Error
  201. $error = error_get_last();
  202. // Check if Last error is of type FATAL
  203. if (isset($error['type']) && $error['type'] == E_ERROR) {
  204. // Fatal Error Occurs
  205. $message = array();
  206. $message[] = 'Error file : ' . str_replace(Psr4::realpath($_SERVER['DOCUMENT_ROOT']), '', $error['file']);
  207. $message[] = 'Error line : ' . $error['line'] . ' on ' . \Qii\Exceptions\Errors::getLineMessage($error['file'], $error['line']);
  208. $message[] = 'Error description : ' . $error['message'];
  209. if (IS_CLI) {
  210. $cli = new \Qii\Response\Cli();
  211. return $cli->stdout(
  212. str_replace("&nbsp;"
  213. , " "
  214. , strip_tags(join(PHP_EOL, preg_replace("/[\n|\r\n]/", PHP_EOL, $message)))
  215. )
  216. );
  217. }
  218. \Qii\Exceptions\Error::showError($message);
  219. }
  220. }
  221. }
  222. //注册名称空间
  223. $namespace = _include(QII_DIR . DS . 'Config' . DS . 'Namespace.php');
  224. Psr4::getInstance()
  225. ->register()
  226. ->setUseNamespaces(isset($namespace['setUseNamespace']) ? $namespace['setUseNamespace']: [])
  227. ->addNamespaces(isset($namespace['addNamespace']) ? $namespace['addNamespace'] : []);
  228. //加载默认语言包
  229. Factory::getInstance('\Qii\Language\Loader')->load('error', QII_DIR . DS . 'Language');
  230. Factory::getInstance('\Qii\Language\Loader')->load('exception', QII_DIR . DS . 'Language');
  231. Factory::getInstance('\Qii\Language\Loader')->load('resource', QII_DIR . DS . 'Language');
  232. //捕获FATAL错误,用户可以选择记录到日志,还是直接显示或者不显示错误
  233. register_shutdown_function('catch_fatal_error');
  234. set_exception_handler(array('\Qii\Exceptions\Errors', 'getError'));
  235. set_error_handler(array('\Qii\Exceptions\Errors', 'getError'), E_USER_ERROR);