Ejemplo n.º 1
0
 /**
  * 查找控制器文件
  *
  * @param string $path_info
  * @param string $dir 指定控制器目录,命令行下默认为shell,网站运行为controllers
  * @return array 返回控制器后的参数数组
  */
 protected static function find_controller($uri, $dir = null, $is_internal = false)
 {
     # 包含目录
     if (isset(Core::$file_list[Core::$project])) {
         $includepath = array(DIR_BULIDER . DS . Core::$project . DS);
     } else {
         $includepath = Core::$include_path;
     }
     $ext = '.controller' . EXT;
     if (IS_SYSTEM_MODE) {
         # 系统调用目录
         $confolder = 'controllers' . DS . '[system]';
     } elseif ($dir && preg_match('#^[a-zA-Z0-9_]+$#', $dir)) {
         $confolder = 'controllers' . DS . '[' . $dir . ']';
     } else {
         if (IS_CLI) {
             $confolder = 'controllers' . DS . '[shell]';
         } else {
             if (Core::$is_admin_url) {
                 $confolder = 'controllers' . DS . '[admin]';
             } else {
                 $confolder = 'controllers';
             }
         }
     }
     # 处理掉2边可能有/的URI
     $new_uri = '/' . trim($uri, '/');
     # 分割参数
     $arguments = explode('/', $new_uri);
     # 默认控制器
     $default_controller = strtolower(Core::$project_config['default_controller']);
     # 记录存在的目录
     $pathArr = array();
     # 控制器目录
     $controller_path = '';
     # 临时包含文件
     $tmp_includepath = $includepath;
     # 寻找可能存在的文件夹
     foreach ($arguments as $argument) {
         $controller_path .= $argument . '/';
         foreach ($tmp_includepath as $k => $path) {
             # 获取完整路径
             $tmppath = rtrim($path . $confolder . DS . str_replace('/', DS, ltrim($controller_path, '/')), DS) . DS;
             if (is_dir($tmppath)) {
                 $pathArr['/' . trim($controller_path, '/')][] = $tmppath;
             } else {
                 # 没有目录则排除
                 unset($tmp_includepath[$k]);
             }
         }
     }
     if (!$pathArr) {
         return false;
     }
     # 倒序,因为最深目录优先级最高
     $pathArr = array_reverse($pathArr);
     // $pathArr 格式类似:
     // Array
     // (
     //    [/test/] => Array
     //        (
     //            [0] => D:\php\myqee_v2\projects\myqee\controllers\test\
     //        )
     //    [/] => Array
     //        (
     //            [0] => D:\php\myqee_v2\projects\myqee\controllers\
     //            [1] => D:\php\myqee_v2\libraries\MyQEE\Core\controllers\
     //        )
     // )
     //
     // 例1
     // URI:/test/abc 筛选控制器优先级排列如下:
     // [no] [file]                                  [action]
     // ----------------------------------------------------------------------------------------
     // 1    test/abc/index.controller.php           default        ->  此时若url结尾没有/且为GET方式则跳转到:/test/abc/
     // ↓
     // 2    test/abc.controller.php                 index          ->  此时若url结尾没有/且为GET方式则跳转到:/test/abc/
     // ↓
     // 3    test/index.controller.php               abc
     // ↓
     // 4    test.controller.php                     abc
     // 5    index.controller.php                    test
     // ↓
     // 6    test/abc.controller.php                 default
     // 7    test.controler.php                      default
     //
     //
     // 例2
     // URL:/test/abc/def 筛选控制器优先级排列如下:
     // [file]                                  [action]
     // ----------------------------------------------------------------------------------------
     // test/abc/def/index.controller.php       default        ->  此时若url结尾没有/且为GET方式则跳转到:/test/abc/def/
     // ↓
     // test/abc/def.controller.php             index          ->  此时若url结尾没有/且为GET方式则跳转到:/test/abc/def/
     // ↓
     // test/abc/index.controller.php           def
     // ↓
     // test/abc.controller.php                 def
     // test/index.controller.php               abc
     // ↓
     // test.controller.php                     abc
     // index.controller.php                    test
     // ↓
     // test/abc/def.controller.php             default
     // test/abc.controller.php                 default
     // test.controller.php                     default
     # 处理根目录下index.controller.php文件的default控制器,即例1中no=1部分
     if (key($pathArr) === $new_uri) {
         # 当前的URI存在最深的根目录
         $uripaths = current($pathArr);
         foreach ($uripaths as $item) {
             $tmp_file = $item . $default_controller . $ext;
             if (is_file($tmp_file)) {
                 $data = array('file' => $tmp_file, 'controller' => trim(str_replace('/', '__', trim($new_uri, '/')) . '__' . $default_controller, '_'), 'function' => 'default');
                 if (HttpIO::check_controller_method($data, $is_internal)) {
                     return array('controller' => $data['controller'], 'action' => '', 'arguments' => array(), 'uri' => $new_uri, 'need_redirect' => substr($uri, -1) == '/' ? false : true);
                 }
             }
         }
     }
     # 处理例1中no=2部分
     $new_uri_sub2 = substr($new_uri, 0, strrpos($new_uri, '/'));
     if ($new_uri_sub2 == '') {
         $new_uri_sub2 = '/';
     }
     if (key($pathArr) === $new_uri_sub2) {
         $con_name = substr($new_uri, strrpos($new_uri, '/') + 1);
         # 当前的URI存在最深的根目录
         $uripaths = current($pathArr);
         foreach ($uripaths as $item) {
             $tmp_file = $item . $con_name . $ext;
             if (is_file($tmp_file)) {
                 $data = array('file' => $tmp_file, 'controller' => trim(str_replace('/', '__', trim($new_uri_sub2, '/')) . '__' . $con_name, '_'), 'function' => 'index');
                 if (HttpIO::check_controller_method($data, $is_internal)) {
                     return array('controller' => $data['controller'], 'action' => 'index', 'arguments' => array(), 'uri' => $new_uri, 'need_redirect' => substr($uri, -1) == '/' ? false : true);
                 }
             }
         }
     }
     # 处理例1中3-5部分,寻找可能存在的控制器文件
     if ($pathArr) {
         foreach ($pathArr as $left_uri => $all_path) {
             $tmpuri = trim(substr($new_uri, strlen($left_uri)), '/');
             $arguments_arr = explode('/', $tmpuri);
             $ar_1 = array_shift($arguments_arr);
             foreach ($all_path as $path) {
                 if ($arguments_arr) {
                     $arguments_arr2 = $arguments_arr;
                     $ar_2 = array_shift($arguments_arr2);
                     $tmp_file = $path . $ar_1 . $ext;
                     if (is_file($tmp_file)) {
                         $data = array('file' => $tmp_file, 'controller' => str_replace('/', '__', ltrim($left_uri . '/', '/') . $ar_1), 'function' => $ar_2);
                         if (HttpIO::check_controller_method($data, $is_internal)) {
                             return array('controller' => $data['controller'], 'action' => $ar_2, 'arguments' => $arguments_arr2, 'uri' => rtrim($left_uri, '/') . '/' . $ar_1 . '/' . $ar_2);
                         }
                     }
                 }
                 $tmp_file = $path . $default_controller . $ext;
                 if (is_file($tmp_file)) {
                     $data = array('file' => $tmp_file, 'controller' => str_replace('/', '__', ltrim($left_uri . '/', '/') . $default_controller), 'function' => $ar_1);
                     if (HttpIO::check_controller_method($data, $is_internal)) {
                         return array('controller' => $data['controller'], 'action' => $ar_1, 'arguments' => $arguments_arr, 'uri' => rtrim($left_uri, '/') . '/' . $ar_1 . '/');
                     }
                 }
             }
         }
     }
     # 处理例1中6-7部分,寻找是否含有默认控制
     if ($pathArr) {
         foreach ($pathArr as $left_uri => $all_path) {
             $tmpuri = trim(substr($new_uri, strlen($left_uri)), '/');
             $arguments_arr = explode('/', $tmpuri);
             $ar_1 = array_shift($arguments_arr);
             foreach ($all_path as $path) {
                 $tmp_file = $path . $ar_1 . $ext;
                 if (is_file($tmp_file)) {
                     $data = array('file' => $tmp_file, 'controller' => str_replace('/', '__', ltrim($left_uri . '/', '/') . $ar_1), 'function' => 'default');
                     if (HttpIO::check_controller_method($data, $is_internal)) {
                         return array('controller' => $data['controller'], 'action' => '', 'arguments' => $arguments_arr, 'uri' => rtrim($left_uri, '/') . '/' . $ar_1 . '/');
                     }
                     break;
                 }
             }
         }
     }
     return false;
 }