core/basic/Kernel.php
<?php
namespace core\basic;
class Kernel
{
private static $controllerPath;
// 启动函数
public static function run()
{
//self::license(); // 授权控制
$path_info = self::getPathInfo(); // 获取路径信息
$path_info = self::urlBlind($path_info); // 地址绑定
$path_info = self::urlRoute($path_info); // 地址路由
$access_path = self::getAccessPath($path_info); // 获取访问路径
self::regAppPath($access_path); // 注册路径信息
self::loadComm(); // 载入应用公共文件
self::loadCache(); // 缓存控制
self::loadController(); // 载入模块控制器
}
// 获取当前路径信息
private static function getPathInfo()
{
// 阿里普通模式: $_SERVER["PATH_INFO"] /List/19.html $_SERVER["REDIRECT_URL"] 无
// 景安普通模式:$_SERVER["PATH_INFO"] /List/19.html $_SERVER["REDIRECT_URL"] /List/19.html
// 阿里重写模式:$_SERVER["PATH_INFO"] 无 $_SERVER["REDIRECT_URL"] /List/19.html
// 景安重写模式:$_SERVER["PATH_INFO"] /List/19.html $_SERVER["REDIRECT_URL"] /index.php/List/19.html
// 路径字符串获取
if (isset($_SERVER['PATH_INFO'])) {
$path_info = $_SERVER['PATH_INFO'];
} elseif (isset($_SERVER["REDIRECT_URL"])) {
$path_info = str_replace('/' . basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['REDIRECT_URL']); // 去掉"/index.php"
$path_info = str_replace(SITE_DIR, '', $path_info); // 去掉部署目录"/a"
} elseif (isset($_GET['s'])) {
$path_info = $_GET['s'];
} else {
$path_info = '';
}
if ($path_info) {
// 分离路径并进行检查
$pattern = '/^\/?([\w-\/\.' . Config::get('url_allow_char') . ']+?)?\/?$/';
if (preg_match($pattern, $path_info)) {
$path_info = preg_replace($pattern, '$1', $path_info);
// 地址文件后缀处理
$url_html_suffix = Config::get('url_suffix');
if (substr($path_info, - strlen($url_html_suffix)) == $url_html_suffix) {
$path_info = substr($path_info, 0, - strlen($url_html_suffix));
}
} else {
error('您访问路径含有非法字符,防注入系统提醒您请勿尝试非法操作!');
}
}
return $path_info;
}
// 地址绑定
private static function urlBlind($pathInfo)
{
$path = '';
// 域名绑定
if (! ! $domains = Config::get('app_domain_blind')) {
$server_name = $_SERVER['SERVER_NAME'];
if (isset($domains[$server_name])) {
$path = $domains[$server_name];
}
}
// 入口绑定
if (defined('URL_BLIND')) {
if ($path) {
if (strpos($path, URL_BLIND) === false && strpos(URL_BLIND, $path) === false) {
error('系统配置的域名地址绑定与入口文件地址绑定冲突,请核对!');
} elseif (strpos($path, URL_BLIND) === false && strpos(URL_BLIND, $path) !== false) {
$path = URL_BLIND;
}
} else {
$path = URL_BLIND;
}
}
if ($path) {
$path = trim_slash($path) . '/' . $pathInfo;
} else {
$path = $pathInfo;
}
return $path;
}
// 地址路由
private static function urlRoute($pathInfo)
{
// URL路由匹配
if (! ! $route = Config::get('url_route')) {
if (! $pathInfo && isset($route['/'])) {
return $route['/'];
}
foreach ($route as $key => $value) {
// 转义正斜杠,避免$reg表达式错误,同时去除两端斜杠
$key = str_replace('/', '\\/', trim_slash($key));
$reg = "/(.*\/|^)" . $key . "(\/.*|$)/Ui";
if (preg_match($reg, $pathInfo)) {
$value = trim_slash($value);
$pathInfo = preg_replace($reg, "$1$value$2", $pathInfo);
break;
}
}
}
return $pathInfo;
}
// 获取路径信息
private static function getAccessPath($pathInfo)
{
$apps = Config::get('public_app', true); // 获取开放的应用
if ($pathInfo) {
$path_info = trim_slash($pathInfo); // 去除两端斜线
$path_array = explode('/', $path_info); // 路径转换为数组
$path_count = count($path_array); // 获取路径长度
if ($path_count >= 3) { // 完整参数
$access_path['m'] = $path_array[0];
$access_path['c'] = $path_array[1];
$access_path['f'] = $path_array[2];
// 获取键值对存入$_GET
for ($i = 3; $i < $path_count; $i = $i + 2) {
if (isset($path_array[$i + 1])) {
$_GET[$path_array[$i]] = $path_array[$i + 1];
} else {
$_GET[$path_array[$i]] = null;
}
}
} elseif ($path_count == 2) { // 只带模块、控制器参数
$access_path['m'] = $path_array[0];
$access_path['c'] = $path_array[1];
} elseif ($path_count == 1) { // 只带模块参数
$access_path['m'] = $path_array[0];
}
}
// 自动设置默认模块、控制器、方法
if (! isset($access_path['m'])) {
$access_path['m'] = $apps[0];
}
if (! isset($access_path['c'])) {
$access_path['c'] = 'Index';
}
if (! isset($access_path['f'])) {
$access_path['f'] = 'index';
}
// 检查模块是否允许访问
if (! in_array(strtolower($access_path['m']), $apps)) {
error('您访问的模块' . $access_path['m'] . '未开放,请核对后重试!');
}
return $access_path;
}
// 注册应用相关参数信息
private static function regAppPath($accessPath)
{
// 定义当前访问路径的基本常量
define('M', strtolower($accessPath['m'])); // 当前访问的模块
self::$controllerPath = self::adjustController($accessPath['c']); // 控制器路径
// 定义当前访问的控制器名称
if (! ! $pos = strrpos(self::$controllerPath, '/')) {
define('C', ucfirst(substr(self::$controllerPath, $pos + 1)));
self::$controllerPath = substr(self::$controllerPath, 0, $pos + 1) . ucfirst(substr(self::$controllerPath, $pos + 1));
} else {
define('C', ucfirst(self::$controllerPath));
self::$controllerPath = ucfirst(self::$controllerPath);
}
define('F', $accessPath['f']); // 当前访问的方法
if (isset($_SERVER["REQUEST_URI"])) { // 定义当前访问路径
define('URL', $_SERVER["REQUEST_URI"]);
} else {
define('URL', $_SERVER["ORIG_PATH_INFO"] . '?' . $_SERVER["QUERY_STRING"]);
}
define('CORE_VERSION', Config::get('core_version')); // 定义框架版本
// 定义控制器路径
define('APP_CONTROLLER_PATH', APP_PATH . '/' . M . '/controller');
// 定义模型路径
define('APP_MODEL_PATH', APP_PATH . '/' . M . '/model');
// 定义当前应用视图路径,如已定义TPL_DIR则执行相关操作
if (($tpl_dir = Config::get('tpl_dir')) && array_key_exists(M, $tpl_dir)) {
// 判断是否全路径
if (strpos($tpl_dir[M], ROOT_PATH) === false) {
define('APP_VIEW_PATH', ROOT_PATH . $tpl_dir[M]);
} else {
define('APP_VIEW_PATH', $tpl_dir[M]);
}
} else {
define('APP_VIEW_PATH', APP_PATH . '/' . M . '/view');
}
}
// 调整控制器
private static function adjustController($string)
{
// 转换点分为多级控制器路径
$string = str_replace('.', '/', $string);
// 下划线字母自动转换大写
$string_arr = explode('_', $string);
if (count($string_arr) > 1) {
$count = count($string_arr);
for ($i = 1; $i < $count; $i ++) {
$string_arr[$i] = ucfirst($string_arr[$i]);
}
$string = implode($string_arr);
}
return $string;
}
// 载入应用公共文件
private static function loadComm()
{
// 调试模式检查目录
Config::get('debug') ? Check::checkAppFile() : '';
// 当前应用配置文件注入
$app_config = APP_PATH . '/' . M . '/config/config.php';
if (file_exists($app_config)) {
Config::assign($app_config);
}
// 定义应用版本
define('APP_VERSION', Config::get('app_version'));
// 请求认证
$auth_arr = Config::get('auth_app', true);
if (is_array($auth_arr) && in_array(M, $auth_arr)) {
//Check::checkAccess(); // 接口服务端验证
if (! ! $sid = isset($_REQUEST['sid']) ? $_REQUEST['sid'] : '') {
session_id($sid); // 设置会话令牌
session_start(); // 启动会话
}
header("Access-Control-Allow-Origin: *"); // 允许跨域请求
} else {
if (! ini_get('session.auto_start')) {
session_start(); // 启动会话
}
Check::checkBs(); // 浏览器类型访问控制
Check::checkOs(); // 操作系统类型访问控制
}
// 当前应用函数载入
$app_function = APP_PATH . '/' . M . '/function/function.php';
if (file_exists($app_function)) {
require $app_function;
}
// 载入应用公共函数文件
if (file_exists(APP_PATH . '/common/function.php')) {
require APP_PATH . '/common/function.php';
}
// 载入应用的公共控制类,方便进行权限等全局性控制
if (file_exists(APP_PATH . '/common/' . ucfirst(M) . 'Controller.php')) {
$comm_class_name = '\\app\\common\\' . ucfirst(M) . 'Controller';
$comm_class = new $comm_class_name();
}
}
// 根据路径信息载入对应的模块控制器
private static function loadController()
{
// 载入当前访问的控制器
$class_file = self::$controllerPath . 'Controller.php';
$class_file_path = APP_CONTROLLER_PATH . '/' . $class_file;
// 配置类名
$class_name = '\\app\\' . M . '\\controller\\' . str_replace('/', '\\', self::$controllerPath) . 'Controller';
$function = F;
if (! file_exists($class_file_path)) {
error('控制器文件不存在!您访问的' . M . '模块下不存在' . $class_file . '控制器类文件!');
}
if (! class_exists($class_name)) {
error('类' . $class_name . '不存在!类文件' . $class_file_path . '中无法找到!');
}
$controller = new $class_name();
if (method_exists($class_name, $function)) {
if (strtolower($class_name) != strtolower($function)) {
$return = $controller->$function();
} else {
$return = $controller;
}
} else {
if (method_exists($class_name, '_empty')) {
$return = $controller->_empty();
} else {
error('方法不存在!' . M . '模块下控制器文件' . $class_file . '中不存在您调用的方法' . $function . ',可能正在开发中,请耐心等待!');
}
}
// 如果有返回值则执行按照格式输出
if ($return !== null) {
Response::handle($return);
}
}
// 非调试模式,当开启缓存且缓存文件存在并未过期则直接载入
private static function loadCache()
{
$cacheFile = RUN_PATH . '/cache/' . md5(URL . session('acode')) . '.html'; // 缓存文件;
if (Config::get('tpl_html_cache') && file_exists($cacheFile) && time() - filemtime($cacheFile) < Config::get('tpl_html_cache_time')) {
include $cacheFile;
exit();
}
}
// 授权控制
private static function license()
{
if (! ! $sn = Config::get('sn', true)) {
$host = $_SERVER['HTTP_HOST'];
$sip = isset($_SERVER['LOCAL_ADDR']) ? $_SERVER['LOCAL_ADDR'] : $_SERVER['SERVER_ADDR'];
$root = substr($host, strpos($host, '.') + 1);
$result = strtoupper(substr(md5(substr(sha1($root), 0, 10)), 10, 10));
if (time() > strtotime('2018-5-1') && $sip != '127.0.0.1' && ! in_array($result, $sn)) {
error('未匹配到本域名有效授权码,请核对后再试!');
}
} else {
error('配置文件中授权码为空,请核对后再试!');
}
}
}