protected static function _class2url(&$class) { $strpos = strpos($class, '_'); $prefix = ''; if ($strpos !== false) { $prefix = strtolower(substr($class, 0, $strpos)); } if ($prefix == 'i18n') { $dir = 'i18n'; $class = substr($class, 5); } elseif ($prefix == 'model') { $dir = 'models'; $class = substr($class, 6); } elseif ($prefix == 'orm') { $dir = 'orm'; # 对ORM做些特殊处理 # 将ORM_Test_Finder转化成Test_Test.Finder # 将ORM_Test_Test2_Finder转化成Test_Test_Test2.Finder $class = ltrim(preg_replace('#^orm(?:_(.*))?_([a-z0-9]+)_([a-z0-9]+)$#i', '$1_$2', $class), '_'); } elseif ($prefix == 'controller') { $dir = HttpIO::current_controller()->dir; $class = substr($class, 11); } elseif ($prefix == 'shell') { $dir = 'shell'; $class = substr($class, 5); } else { $dir = 'classes'; } return $dir; }
/** * 执行请求,并将输出结果返回 * * @param string $path_info 路径信息 * @param boolean $print 是否直接输出 * @param boolean $use_route 是否尝试在路由中搜索 * @param boolean $is_internal 是否内部调用,默认:否 * @param string $controller_dir 指定控制器目录,命令行下默认为shell,网站运行为controllers * @return string */ public static function execute($uri, $print = true, $use_route = true, $is_internal = false, $controller_dir = null) { $ob_open = false; if (!$print && !IS_CLI) { ob_start(); $ob_open = true; } $params = false; # 路由设置 if (IS_CLI != true && true === $use_route && Core::$project_config['route'] && ($route = Core::route()->get($uri))) { $params = $route; # 默认控制器 if ($params['controller']) { $params['controller'] = str_replace('/', '_', $params['controller']); } else { $params['controller'] = Core::$project_config['default_controller']; } $dir = 'controllers'; if (IS_SYSTEM_MODE) { $file = '[system]/' . $params['controller']; } elseif (IS_CLI) { $file = '[shell]/' . $params['controller']; } elseif (Core::$is_admin_url) { $file = '[admin]/' . $params['controller']; } else { $file = $params['controller']; } if ($controller_dir && preg_match('#^[a-zA-Z0-9_]+$#', $controller_dir)) { $dir = $controller_dir; $file = strtolower(str_replace('__', '/', $file)); } if (!Core::find_file($dir, $file, null, true)) { Core::debug()->error('没有找到控制器:' . $params['controller']); if ($ob_open) { ob_end_clean(); } return false; } $is_use_route = true; if (Core_Route::$last_route) { Core_Route::$current_route = Core_Route::$last_route; Core_Route::$route_list[] = Core_Route::$current_route; } } else { $params = HttpIO::find_controller($uri, $controller_dir, $is_internal); if (!IS_CLI && null === HttpIO::$uri && HttpIO::METHOD == 'GET' && !$is_internal && isset($params['need_redirect']) && $params['need_redirect'] == true) { # 页面结尾自动加/ $request = explode('?', $_SERVER['REQUEST_URI'], 2); Core::close_buffers(false); HttpIO::redirect($request[0] . '/' . (isset($request[1]) ? '?' . $request[1] : ''), 301); exit; } $is_use_route = false; } if (false === $params) { Core::debug()->error('没有找到指定页面'); if ($ob_open) { ob_end_clean(); } return false; } # 初始化$uri if (null === HttpIO::$uri) { HttpIO::$uri = $uri; } if (null === HttpIO::$params) { HttpIO::$params = $params; } # 控制器名称 $controller_name = 'Controller_' . $params['controller']; # 参数 $arguments = isset($params['arguments']) ? $params['arguments'] : array(); if (IS_SYSTEM_MODE) { $params['arguments'] = @unserialize(HttpIO::POST('data', HttpIO::PARAM_TYPE_OLDDATA)); } if ($is_internal) { $prefix = 'sub_action'; } else { $prefix = 'action'; } # 方法 $action_name = $params['action']; if (!$action_name) { $action_name = $prefix . '_' . Core::$project_config['default_action']; } else { $action_name = $prefix . '_' . $action_name; } # 如果不存在控制器类则抛404页面 if (!class_exists($controller_name, false)) { Core::debug()->error('控制器:' . $controller_name . '不存在。'); if ($ob_open) { ob_end_clean(); } return false; } # 构造新控制器 if (!isset(HttpIO::$controlers[$controller_name])) { HttpIO::$controlers[$controller_name] = new $controller_name(); } $old_current_controller = HttpIO::$current_controller; HttpIO::$current_controller = $controller = HttpIO::$controlers[$controller_name]; # 存控制器的数据 static $obj_params = array(); if (!isset($obj_params[$controller_name]) || !is_array($obj_params[$controller_name])) { $obj_params[$controller_name] = array(); } if (method_exists($controller, '_callback_get_vars')) { # 将控制器参数记录下来 $obj_params[$controller_name][] = $controller->_callback_get_vars(); } if (method_exists($controller, '_callback_set_vars')) { # 将参数传递给控制器 $controller->_callback_set_vars($params); } if (!$is_internal && !method_exists($controller, $action_name)) { $action_name = $prefix . '_default'; if (!method_exists($controller, $action_name)) { $action_name = '__call'; $arguments = array($action_name, $arguments); if (!method_exists($controller, $action_name)) { Core::debug()->error('控制器:' . $controller_name . '方法:' . $action_name . '不存在。'); if ($ob_open) { ob_end_clean(); } return false; } } } # Method is Public? $ispublicmethod = new ReflectionMethod($controller, $action_name); if (!$ispublicmethod->isPublic()) { Core::debug()->error('控制器:' . $controller_name . '方法:' . $action_name . '受保护。'); if ($ob_open) { ob_end_clean(); } return false; } if (!$is_internal) { if (method_exists($controller, 'before')) { $controller->before(); } } # 执行方法 $count_arguments = count($arguments); switch ($count_arguments) { case 0: $controller->{$action_name}(); break; case 1: $controller->{$action_name}($arguments[0]); break; case 2: $controller->{$action_name}($arguments[0], $arguments[1]); break; case 3: $controller->{$action_name}($arguments[0], $arguments[1], $arguments[2]); break; case 4: $controller->{$action_name}($arguments[0], $arguments[1], $arguments[2], $arguments[3]); break; default: # Resort to using call_user_func_array for many segments call_user_func_array(array($controller, $action_name), $arguments); break; } if (!$is_internal) { if (method_exists($controller, 'after')) { $controller->after(); } } # 将原来的数据重新设置回去 if (method_exists($controller, '_callback_set_vars')) { if (is_array($obj_params[$controller_name])) { $tmp_params = array_pop($obj_params[$controller_name]); $controller->_callback_set_vars($tmp_params); } } HttpIO::$current_controller = $old_current_controller; unset($old_current_controller); unset($controller); if (!count($obj_params[$controller_name])) { unset(HttpIO::$controlers[$controller_name]); } if (true == $is_use_route) { # 路由列队 array_pop(Core_Route::$route_list); if (Core_Route::$route_list) { end(Core_Route::$route_list); $key = key(Core_Route::$route_list); Core_Route::$last_route = Core_Route::$current_route = Core_Route::$route_list[$key]; } else { Core_Route::$route_list = null; } } if (!$print && !IS_CLI) { $output = ob_get_clean(); return $output; } else { if ($ob_open) { ob_end_clean(); } return ''; } }