选择语言 :

 Core_Core::find_controller

寻找控制器

array Core_Core::find_controller( )
返回值
  • array
File: ./core/classes/core.class.php
protected static function find_controller($uri)
{
    $uri = ltrim($uri, '/');

    if (Core::$config['url_suffix'] && substr(strtolower($uri), -strlen(Core::$config['url_suffix']))==Core::$config['url_suffix'])
    {
        $uri = substr($uri, 0, -strlen(Core::$config['url_suffix']));
    }

    if (!IS_SYSTEM_MODE && isset(Core::$config['route']) && Core::$config['route'])
    {
        # 有路由配置,首先根据路由配置查询控制器
        $found_route = Route::get($uri);

        if ($found_route)
        {
            if (!isset($found_route['controller']) || !$found_route['controller'])
            {
                if (IS_DEBUG)Core::debug()->error('The route not match controller');
                Core::show_404();
            }

            return array
            (
                'class'  => 'Controller_' . preg_replace('#[^a-zA-Z0-9_]#', '_', trim($found_route['controller'])),
                'route'  => $found_route,
            );
        }
        else
        {
            unset($found_route);
        }
    }

    if ($uri!='')
    {
        $uri_arr = explode('/', strtolower($uri));
    }
    else
    {
        $uri_arr = array();
    }

    if (IS_DEBUG)
    {
        Core::debug()->log('/'. $uri, 'find controller uri');
    }

    $include_path = Core::$include_path;

    # log
    $find_log = $find_path_log = array();

    # 控制器目录
    $controller_dir = Core::$dir_setting['controller'][0];

    if (IS_SYSTEM_MODE)
    {
        $controller_dir .= '-system';
    }
    elseif (IS_ADMIN_MODE)
    {
        $controller_dir .= '-admin';
    }
    elseif (IS_REST_MODE)
    {
        $controller_dir .= '-rest';
    }
    elseif (IS_CLI)
    {
        $controller_dir .= '-shell';
    }

    # 首先找到存在的目录
    $found_path = array();
    foreach ($include_path as $ns => $ipath)
    {
        if($ipath)foreach ($ipath as $lib_ns => $path)
        {
            if ($ns==='library')
            {
                $tmp_ns = 'library_' . str_replace('.', '_', $lib_ns);
            }
            else
            {
                $tmp_ns = $ns;
            }

            $tmp_str  = $real_path = $real_class = '';
            $tmp_path = $path . $controller_dir . DS;
            $ids      = array();

            foreach ($uri_arr as $uri_path)
            {
                $ds = DS;
                if ($uri_path==='')
                {
                    if (count($uri_arr)>1)
                    {
                        break;
                    }
                    $real_uri_path = '';
                    $ds = '';
                }
                elseif (is_numeric($uri_path))
                {
                    $real_uri_path = '_id';
                    $ids[] = $uri_path;
                }
                elseif ($uri_path == '_id')
                {
                    # 不允许直接在URL中使用_id
                    break;
                }
                elseif (preg_match('#[^a-z0-9_]#i', $uri_path))
                {
                    # 不允许非a-z0-9_的字符在控制中
                    break;
                }
                else
                {
                    $real_uri_path = $uri_path;
                }

                $tmpdir = $tmp_path . $real_path . $real_uri_path . $ds;
                if (IS_DEBUG)
                {
                    $find_path_log[] = Core::debug_path($tmpdir);
                }
                $real_path  .= $real_uri_path . DS;
                $real_class .= $real_uri_path . '_';
                $tmp_str    .= $uri_path . DS;

                if (is_dir($tmpdir))
                {
                    $found_path[$tmp_str][] = array
                    (
                        $tmp_ns,
                        $tmpdir,
                        ltrim($real_class, '_'),
                        $ids,
                    );
                }
                else
                {
                    break;
                }
            }

            // 根目录的
            if (is_dir($tmp_path))
            {
                $found_path[''][] = array
                (
                    $tmp_ns,
                    $tmp_path,
                    '',
                    array(),
                );

                if (IS_DEBUG)
                {
                    $find_path_log[] = Core::debug_path($tmp_path);
                }
            }
        }
    }

    unset($ids);
    $found = null;

    # 寻找可能的文件
    if ($found_path)
    {
        # 调整优先级
        krsort($found_path);

        foreach ($found_path as $path => $all_path)
        {
            $path_len = strlen($path);
            $tmp_p    = substr($uri, $path_len);

            if (strlen($tmp_p)>0)
            {
                $args = explode('/', substr($uri, $path_len));
            }
            else
            {
                $args = array();
            }

            $the_id    = array();
            $tmp_class = array_shift($args);
            $tmp_arg   = $tmp_class;
            $directory = rtrim('/'. substr($uri, 0, $path_len) . $tmp_class, '/');

            if (0===strlen($tmp_class))
            {
                $tmp_class = 'index';
            }
            elseif (is_numeric($tmp_class))
            {
                $the_id = array
                (
                    $tmp_class
                );
                $tmp_class = '_id';
            }
            elseif ($tmp_class == '_id')
            {
                continue;
            }

            $real_class = $tmp_class;
            $tmp_class  = strtolower($tmp_class);

            // 记录找到的index.controller.php
            $found_index_class = null;

            if (IS_DEBUG)
            {
                $find_log2 = array();
            }

            foreach ($all_path as $tmp_arr)
            {
                list($ns, $tmp_path, $real_path, $ids) = $tmp_arr;
                $tmpfile = $tmp_path . $tmp_class . Core::$dir_setting['controller'][1] . EXT;

                if (IS_DEBUG)
                {
                    $find_log[] = Core::debug_path($tmpfile);
                }

                if (is_file($tmpfile))
                {
                    if ($the_id)
                    {
                        $ids = array_merge($ids, $the_id);
                    }

                    if ($directory && substr($directory, -1-strlen($tmp_class))=='/'.$tmp_class)
                    {
                        $directory = substr($directory, 0, -1-strlen($tmp_class));
                    }

                    $found = array
                    (
                        'file'   => $tmpfile,
                        'dir'    => $directory,
                        'ns'     => $ns,
                        'class'  => 'Controller_' . $real_path . $real_class,
                        'args'   => $args,
                        'ids'    => $ids,
                    );

                    break 2;
                }
                elseif (!$found_index_class && $tmp_class!='default')
                {
                    // 记录 index.controller.php 控制器
                    $tmpfile = $tmp_path . 'default' . Core::$dir_setting['controller'][1] . EXT;
                    if (IS_DEBUG)
                    {
                        $find_log2[] = Core::debug_path($tmpfile);
                    }

                    if (is_file($tmpfile))
                    {
                        if (null!==$tmp_arg)
                        {
                            array_unshift($args, $tmp_arg);

                            if (strlen($tmp_arg)>0)
                            {
                                $directory = substr($directory, 0, -strlen($tmp_arg) - 1);
                            }
                        }

                        $found_index_class = array
                        (
                            'file'   => $tmpfile,
                            'dir'    => $directory,
                            'ns'     => $ns,
                            'class'  => 'Controller_' . $real_path . 'Default',
                            'args'   => $args,
                            'ids'    => $ids,
                        );
                    }
                }
            }

            if (IS_DEBUG && $find_log2)
            {
                $find_log = array_merge($find_log, $find_log2);
            }

            // index.controller.php 文件
            if (!$found && $found_index_class)
            {
                $found = $found_index_class;
                break;
            }
        }
    }

    if (IS_DEBUG)
    {
        Core::debug()->group('find controller path');
        foreach ($find_path_log as $value)
        {
            Core::debug()->log($value);
        }
        Core::debug()->groupEnd();

        Core::debug()->group('find controller files');
        foreach ($find_log as $value)
        {
            Core::debug()->log($value);
        }
        Core::debug()->groupEnd();

        if ($found)
        {
            $found2 = $found;
            $found2['file'] = Core::debug_path($found2['file']);
            Core::debug()->log($found2, 'found contoller');
        }
        else
        {
            Core::debug()->log('/'. $uri, 'not found contoller');
        }
    }

    if (is_array($found) && isset($found['class']))
    {
        $found['class'] = preg_replace('#[^a-zA-Z0-9_]#', '_', trim($found['class']));
    }

    return $found;
}