diff --git a/base.php b/base.php index 8a77742b..caf5cea0 100644 --- a/base.php +++ b/base.php @@ -19,6 +19,7 @@ defined('TRAIT_PATH') or define('TRAIT_PATH', THINK_PATH . 'traits/'); defined('CORE_PATH') or define('CORE_PATH', LIB_PATH . 'think/'); defined('ORG_PATH') or define('ORG_PATH', LIB_PATH . 'org/'); defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . '/'); +defined('COMMON_MODULE') or define('COMMON_MODULE', 'common'); defined('RUNTIME_PATH') or define('RUNTIME_PATH', realpath(APP_PATH) . '/runtime/'); defined('DATA_PATH') or define('DATA_PATH', RUNTIME_PATH . 'data/'); defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'log/'); diff --git a/convention.php b/convention.php index 6d308d74..04fc4034 100644 --- a/convention.php +++ b/convention.php @@ -5,12 +5,12 @@ return [ 'app_status' => 'debug', // PATHINFO变量名 用于兼容模式 'var_pathinfo' => 's', - 'extra_config_list' => [], + // 兼容PATH_INFO获取 'pathinfo_fetch' => 'ORIG_PATH_INFO,REDIRECT_PATH_INFO,REDIRECT_URL', + // 扩展配置文件 + 'extra_config_list' => ['database', 'route'], // pathinfo分隔符 'pathinfo_depr' => '/', - // 是否显示模块 - 'require_module' => true, // 默认模块名 'default_module' => 'index', // 默认控制器名 @@ -43,9 +43,9 @@ return [ 'default_jsonp_handler' => 'jsonpReturn', 'var_jsonp_handler' => 'callback', 'template_engine' => 'think', - 'common_module' => 'common', 'action_bind_class' => false, 'url_module_map' => [], + 'response_exit' => true, /* 错误设置 */ //错误显示信息,非调试模式有效 diff --git a/library/think/app.php b/library/think/app.php index b0298478..152f95bd 100644 --- a/library/think/app.php +++ b/library/think/app.php @@ -25,33 +25,39 @@ class App */ public static function run(array $config = []) { - if (version_compare(PHP_VERSION, '5.4.0', '<')) { throw new Exception('require PHP > 5.4.0 !'); } + + // 初始化公共模块 + self::initModule(COMMON_MODULE, $config); + + // 读取扩展配置文件 + if ($config['extra_config_list']) { + foreach ($config['extra_config_list'] as $file) { + Config::load($file, $file); + } + } + + // 获取配置参数 + $config = Config::get(); + // 日志初始化 Log::init($config['log']); - // 缓存初始化 Cache::connect($config['cache']); - // 加载框架底层语言包 - if (is_file(THINK_PATH . 'Lang/' . strtolower($config['default_lang']) . EXT)) { - Lang::set(include THINK_PATH . 'Lang/' . strtolower($config['default_lang']) . EXT); - } + // 默认语言 + $lang = strtolower($config['default_lang']); + Lang::range($lang); + // 加载默认语言包 + Lang::load(THINK_PATH . 'Lang/' . $lang . EXT); - if (is_file(APP_PATH . 'build.php')) { - // 自动化创建脚本 - Create::build(include APP_PATH . 'build.php'); - } - - // 初始化公共模块 - self::initModule(APP_PATH . $config['common_module'] . '/', $config); // 监听app_init Hook::listen('app_init'); // 启动session - if ($config['use_session']) { + if (!IS_CLI && $config['use_session']) { Session::init($config['session']); } @@ -66,22 +72,7 @@ class App // 安全检测 $instance = false; } elseif ($config['action_bind_class']) { - // 操作绑定到类:模块\controller\控制器\操作 - if (is_dir(MODULE_PATH . CONTROLLER_LAYER . '/' . str_replace('.', '/', CONTROLLER_NAME))) { - $namespace = MODULE_NAME . '\\' . CONTROLLER_LAYER . '\\' . str_replace('.', '\\', CONTROLLER_NAME) . '\\'; - } else { - // 空控制器 - $namespace = MODULE_NAME . '\\' . CONTROLLER_LAYER . '\\' . $config['empty_controller'] . '\\'; - } - $actionName = strtolower(ACTION_NAME); - if (class_exists($namespace . $actionName)) { - $class = $namespace . $actionName; - } elseif (class_exists($namespace . '_empty')) { - // 空操作 - $class = $namespace . '_empty'; - } else { - throw new Exception('_ERROR_ACTION_:' . ACTION_NAME); - } + $class = self::bindActionClass($config['empty_controller']); $instance = new $class; // 操作绑定到类后 固定执行run入口 $action = 'run'; @@ -107,30 +98,9 @@ class App if ($method->isPublic()) { // URL参数绑定检测 if ($config['url_params_bind'] && $method->getNumberOfParameters() > 0) { - switch ($_SERVER['REQUEST_METHOD']) { - case 'POST': - $vars = array_merge($_GET, $_POST); - break; - case 'PUT': - parse_str(file_get_contents('php://input'), $vars); - break; - default: - $vars = $_GET; - } - $params = $method->getParameters(); - $paramsBindType = $config['url_parmas_bind_type']; - foreach ($params as $param) { - $name = $param->getName(); - if (1 == $paramsBindType && !empty($vars)) { - $args[] = array_shift($vars); - }if (0 == $paramsBindType && isset($vars[$name])) { - $args[] = $vars[$name]; - } elseif ($param->isDefaultValueAvailable()) { - $args[] = $param->getDefaultValue(); - } else { - throw new Exception('_PARAM_ERROR_:' . $name); - } - } + // 获取绑定参数 + $args = self::getBindParams($method, $config['url_parmas_bind_type']); + // 全局过滤 array_walk_recursive($args, 'Input::filterExp'); $data = $method->invokeArgs($instance, $args); } else { @@ -139,7 +109,12 @@ class App // 操作方法执行完成监听 Hook::listen('action_end', $data); // 返回数据 - Response::returnData($data, $config['default_return_type']); + $data = Response::returnData($data, $config['default_return_type']); + if ($config['response_exit']) { + exit($data); + } else { + echo $data; + } } else { // 操作方法不是Public 抛出异常 throw new \ReflectionException(); @@ -156,46 +131,89 @@ class App return; } + // 操作绑定到类:模块\controller\控制器\操作类 + private static function bindActionClass($emptyController) + { + if (is_dir(MODULE_PATH . CONTROLLER_LAYER . '/' . str_replace('.', '/', CONTROLLER_NAME))) { + $namespace = MODULE_NAME . '\\' . CONTROLLER_LAYER . '\\' . str_replace('.', '\\', CONTROLLER_NAME) . '\\'; + } else { + // 空控制器 + $namespace = MODULE_NAME . '\\' . CONTROLLER_LAYER . '\\' . $emptyController . '\\'; + } + $actionName = strtolower(ACTION_NAME); + if (class_exists($namespace . $actionName)) { + $class = $namespace . $actionName; + } elseif (class_exists($namespace . '_empty')) { + // 空操作 + $class = $namespace . '_empty'; + } else { + throw new Exception('_ERROR_ACTION_:' . ACTION_NAME); + } + return $class; + } + + private static function getBindParams($method, $paramsBindType) + { + switch ($_SERVER['REQUEST_METHOD']) { + case 'POST': + $vars = array_merge($_GET, $_POST); + break; + case 'PUT': + parse_str(file_get_contents('php://input'), $vars); + break; + default: + $vars = $_GET; + } + $params = $method->getParameters(); + foreach ($params as $param) { + $name = $param->getName(); + if (1 == $paramsBindType && !empty($vars)) { + $args[] = array_shift($vars); + }if (0 == $paramsBindType && isset($vars[$name])) { + $args[] = $vars[$name]; + } elseif ($param->isDefaultValueAvailable()) { + $args[] = $param->getDefaultValue(); + } else { + throw new Exception('_PARAM_ERROR_:' . $name); + } + } + return $args; + } /** * 初始化模块 * @access private * @return void */ - private static function initModule($path, &$config) + private static function initModule($module, &$config) { // 加载初始化文件 - if (is_file($path . 'init' . EXT)) { - include $path . 'init' . EXT; + if (is_file(APP_PATH . $module . '/init' . EXT)) { + include APP_PATH . $module . '/init' . EXT; } else { - // 检测配置文件 - if (is_file($path . 'config' . EXT)) { - $config = Config::set(include $path . 'config' . EXT); + + // 定位模块目录 + $module = COMMON_MODULE == $module ? '' : $module . '/'; + // 加载模块配置 + $config = Config::load($module . 'config'); + + // 加载应用状态配置 + if ($config['app_status'] && is_file(APP_PATH . $module . $config['app_status'] . EXT)) { + $config = Config::load($module . $config['app_status']); } - // 检测额外配置 - if ($config['extra_config_list']) { - foreach ($config['extra_config_list'] as $conf) { - if (is_file($path . $conf . EXT)) { - $config = Config::set(include $path . $conf . EXT); - } - } - } - - // 加载应用状态配置文件 - if ($config['app_status'] && is_file($path . $config['app_status'] . EXT)) { - $config = Config::set(include $path . $config['app_status'] . EXT); - } // 加载别名文件 - if (is_file($path . 'alias' . EXT)) { - Loader::addMap(include $path . 'alias' . EXT); - } - // 加载公共文件 - if (is_file($path . 'common' . EXT)) { - include $path . 'common' . EXT; + if (is_file(APP_PATH . $module . 'alias' . EXT)) { + Loader::addMap(include APP_PATH . $module . 'alias' . EXT); } + // 加载行为扩展文件 - if (is_file($path . 'tags' . EXT)) { - Hook::import(include $path . 'tags' . EXT); + if (is_file(APP_PATH . $module . 'tags' . EXT)) { + Hook::import(include APP_PATH . $module . 'tags' . EXT); + } + + // 加载公共文件 + if (is_file(APP_PATH . $module . 'common' . EXT)) { + include APP_PATH . $module . 'common' . EXT; } } } @@ -217,7 +235,7 @@ class App } // 检测域名部署 - if (!IS_CLI && isset($config['sub_domain_deploy']) && $config['sub_domain_deploy']) { + if (!IS_CLI && !empty($config['domain_deploy'])) { Route::checkDomain(); } @@ -256,10 +274,9 @@ class App } // 路由检测 if (!empty($config['url_route_on'])) { - // 开启路由 则检测路由配置 并默认读取 url_route_rules 参数 - Route::register($config['url_route_rules']); + // 开启路由 则检测路由配置 + Route::register($config['route']); $result = Route::check(__INFO__, $config['pathinfo_depr']); - if (false === $result) { // 路由无效 if ($config['url_route_must']) { @@ -298,7 +315,7 @@ class App define('VIEW_PATH', MODULE_PATH . VIEW_LAYER . '/'); // 初始化模块 - self::initModule(MODULE_PATH, $config); + self::initModule(MODULE_NAME, $config); } else { throw new Exception('module not exists :' . MODULE_NAME); } @@ -308,6 +325,5 @@ class App // 获取操作名 define('ACTION_NAME', strip_tags(strtolower($result[2] ?: $config['default_action']))); - } } diff --git a/library/think/config.php b/library/think/config.php index ab383955..415b8c0d 100644 --- a/library/think/config.php +++ b/library/think/config.php @@ -37,7 +37,8 @@ class Config // 加载配置文件 public static function load($file, $name = '', $range = '') { - return self::set(include $file, $name, $range); + $file = is_file($file) ? $file : APP_PATH . $file . EXT; + return is_file($file) ? self::set(include $file, $name, $range) : self::$config[$range]; } // 检测配置是否存在 diff --git a/library/think/create.php b/library/think/create.php index 922e1854..9fb12262 100644 --- a/library/think/create.php +++ b/library/think/create.php @@ -49,17 +49,17 @@ class Create foreach ($file as $val) { $filename = APP_PATH . $module . '/' . $path . '/' . strtolower($val) . EXT; switch ($path) { - case 'controller': // 控制器 + case 'controller': // 控制器 if (!is_file($filename)) { file_put_contents($filename, "model = $options['model']; $this->parseBind(!empty($options['bind']) ? $options['bind'] : []); $sql = $this->buildSelectSql($options); - $result = $this->query($sql, !empty($options['fetch_sql']) ? true : false, !empty($options['read_master']) ? true : false); + $result = $this->query($sql, !empty($options['fetch_sql']) ? true : false, !empty($options['master']) ? true : false); return $result; } @@ -1169,13 +1169,11 @@ abstract class Driver */ protected function initConnect($master = true) { - if (!empty($this->config['deploy'])) - // 采用分布式数据库 - { + if (!empty($this->config['deploy'])) { + // 采用分布式数据库 $this->_linkID = $this->multiConnect($master); - } else - // 默认单数据库 - if (!$this->_linkID) { + } elseif (!$this->_linkID) { + // 默认单数据库 $this->_linkID = $this->connect(); } diff --git a/library/think/error.php b/library/think/error.php index 1217304a..bbe077e0 100644 --- a/library/think/error.php +++ b/library/think/error.php @@ -99,7 +99,7 @@ class Error $data['code'] = $code; $data['msg'] = $message; $data['time'] = NOW_TIME; - Response::returnData($data); + exit(Response::returnData($data)); } $e = []; if (APP_DEBUG) { @@ -129,7 +129,7 @@ class Error } } // 包含异常页面模板 - include Config::get('exception_tmpl'); - exit; + $data = include Config::get('exception_tmpl'); + exit(Response::returnData($data)); } } diff --git a/library/think/lang.php b/library/think/lang.php index 4a1e04e4..c5581fa4 100644 --- a/library/think/lang.php +++ b/library/think/lang.php @@ -14,11 +14,11 @@ namespace think; class Lang { // 语言参数 - private static $lang = []; - // 作用域 - private static $range = '_sys_'; + private static $lang = []; + // 语言作用域 + private static $range = ''; - // 设定语言参数的作用域 + // 设定语言参数的作用域(语言) public static function range($range) { self::$range = $range; @@ -42,6 +42,20 @@ class Lang } } + /** + * 加载语言定义(不区分大小写) + * @param string $file 语言文件 + * @param string $range 作用域 + * @return mixed + */ + public static function load($file, $range = '') + { + $range = $range ? $range : self::$range; + $lang = is_file($file) ? include $file : []; + // 批量定义 + return self::$lang[$range] = array_merge(self::$lang[$range], array_change_key_case($lang)); + } + /** * 获取语言定义(不区分大小写) * @param string|null $name 语言变量 diff --git a/library/think/model.php b/library/think/model.php index a03c568e..b95e406d 100644 --- a/library/think/model.php +++ b/library/think/model.php @@ -1414,9 +1414,9 @@ class Model * @access public * @return Model */ - public function readMaster() + public function master() { - $this->options['read_master'] = true; + $this->options['master'] = true; return $this; } } diff --git a/library/think/response.php b/library/think/response.php index c369be5e..a90f665f 100644 --- a/library/think/response.php +++ b/library/think/response.php @@ -14,6 +14,7 @@ namespace think; use think\Config as Config; use think\Transform as Transform; use think\Url as Url; + class Response { @@ -54,7 +55,7 @@ class Response $data = $handler . '(' . Transform::jsonEncode($data) . ');'; break; } - exit($data); + return $data; } /** diff --git a/library/think/route.php b/library/think/route.php index 0633d25f..aa8d7bf1 100644 --- a/library/think/route.php +++ b/library/think/route.php @@ -156,7 +156,6 @@ class Route } if (is_array($rule)) { define('BIND_MODULE', $rule[0]); - //$_GET[VAR_MODULE] = $rule[0]; if (isset($rule[1])) { // 传入参数 parse_str($rule[1], $parms); @@ -171,7 +170,6 @@ class Route } } else { define('BIND_MODULE', $rule); - //$_GET[VAR_MODULE] = $rule; } } }