config = $config; } // 运行程序 public function run() { spl_autoload_register(array($this, 'loadClass')); $this->setReporting(); $this->removeMagicQuotes(); $this->unregisterGlobals(); $this->setDbConfig(); $this->route(); } // 路由处理 - 最终修复版 public function route() { $controllerName = 'Login'; $actionName = $this->config['defaultAction']; $param = array(); // 获取请求 URI $requestUri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/'; // 清除?之后的内容(查询字符串) $position = strpos($requestUri, '?'); if ($position !== false) { $requestUri = substr($requestUri, 0, $position); } // 解析 URL 路径 $url = trim($requestUri, '/'); if (!empty($url)) { // 分割 URL $urlArray = explode('/', $url); // 过滤:只移除空值和 index.php // 不再自动移除项目目录名,避免误判 $urlArray = array_values(array_filter($urlArray, function($value) { $lowerValue = strtolower($value); return $value !== '' && $lowerValue !== 'index.php'; })); // 现在 urlArray 应该是 [控制器,动作,参数...] if (!empty($urlArray)) { // 获取控制器名(首字母大写) $controllerName = ucfirst(strtolower($urlArray[0])); // 获取动作名 if (isset($urlArray[1]) && !empty($urlArray[1])) { $actionName = $urlArray[1]; } // 获取参数 if (isset($urlArray[2])) { $param = array_slice($urlArray, 2); } } } // 构建控制器类名 $controller = 'app\\controllers\\' . $controllerName . 'Controller'; // 检查控制器是否存在 if (!class_exists($controller)) { if (APP_DEBUG) { exit('

控制器不存在:' . htmlspecialchars($controllerName) . '

' . '

访问的 URL: ' . htmlspecialchars($requestUri) . '

' . '

解析后的路径:' . htmlspecialchars(implode('/', $urlArray ?? [])) . '

' . '

请检查 URL 是否正确。

'); } $this->notFound(); } // 检查方法是否存在(如果控制器有 __call 魔术方法,允许动态方法通过) if (!method_exists($controller, $actionName) && !method_exists($controller, '__call')) { if (APP_DEBUG) { exit('

方法不存在:' . htmlspecialchars($actionName) . '

' . '

控制器:' . htmlspecialchars($controllerName) . 'Controller

' . '

可用方法:

' . htmlspecialchars(implode(', ', get_class_methods($controller))) . '

'); } $this->notFound(); } // 实例化控制器并调用方法 $dispatch = new $controller($controllerName, $actionName); call_user_func_array(array($dispatch, $actionName), $param); } // 统一的 404 响应(生产环境不泄露任何细节) protected function notFound() { if (!headers_sent()) { header('HTTP/1.1 404 Not Found'); } exit('404 Not Found'); } // 检测开发环境 public function setReporting() { if (APP_DEBUG === true) { error_reporting(E_ALL); ini_set('display_errors','On'); } else { error_reporting(E_ALL); ini_set('display_errors','Off'); ini_set('log_errors', 'On'); // 自定义异常处理 — 防止敏感信息泄露 set_exception_handler(function($e) { error_log('Unhandled exception: ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine()); if (!headers_sent()) { header('HTTP/1.1 500 Internal Server Error'); } exit('系统内部错误,请稍后重试'); }); } } // 删除敏感字符 public function stripSlashesDeep($value) { $value = is_array($value) ? array_map(array($this, 'stripSlashesDeep'), $value) : stripslashes($value); return $value; } // 检测敏感字符并删除(已废弃) public function removeMagicQuotes() { // 不再处理 } // 检测自定义全局变量并移除 public function unregisterGlobals() { if (ini_get('register_globals')) { $array = array('_SESSION', '_POST', '_GET', '_COOKIE', '_REQUEST', '_SERVER', '_ENV', '_FILES'); foreach ($array as $value) { foreach ($GLOBALS[$value] as $key => $var) { if ($var === $GLOBALS[$key]) { unset($GLOBALS[$key]); } } } } } // 配置数据库信息 public function setDbConfig() { if ($this->config['db']) { define('DB_HOST', $this->config['db']['host']); define('DB_NAME', $this->config['db']['dbname']); define('DB_USER', $this->config['db']['username']); define('DB_PASS', $this->config['db']['password']); } } // 自动加载类 public function loadClass($className) { $classMap = $this->classMap(); if (isset($classMap[$className])) { $file = $classMap[$className]; } elseif (strpos($className, '\\') !== false) { $file = APP_PATH . str_replace('\\', '/', $className) . '.php'; if (!is_file($file)) { return; } } else { return; } include $file; } // 内核文件命名空间映射关系 protected function classMap() { return [ 'core\base\Controller' => CORE_PATH . '/base/Controller.php', 'core\base\Model' => CORE_PATH . '/base/Model.php', 'core\base\View' => CORE_PATH . '/base/View.php', 'core\db\Db' => CORE_PATH . '/db/Db.php', 'core\db\Sql' => CORE_PATH . '/db/Sql.php', ]; } }