2

嗨,我不会做那样的事情。

http://example.com/ - 主控制器

http://example.com/rules/ - 从数据库获取内容的主控制器,但如果不存在则返回 404 页面。(没关系,没问题。)

但是,如果我在 application/controlles/rules/ 中有子文件夹,我想将其重定向到 Rules 文件夹中的 Main Contorller。

下面的代码可以解决问题,但我不知道它是如何正确实现的。在 routes.php:

$route['default_controller'] = "main";
$route['404_override'] = '';

$dirtest = $route['(:any)'];

if (is_dir(APPPATH.'controllers/'.$dirtest)) {
$route['(:any)'] = $dirtest.'/$1';
} else {
$route['(:any)'] = 'main/index/$1';
}

好的,我有什么:

控制器/main.php

class Main extends CI_Controller {

    public function __construct()
        {
            parent::__construct();
            $this->load->model('main_model');
        }

    public function index($method = null)
    {
        if (is_dir(APPPATH.'controllers/'.$method)) {
            // Need re-rout to the application/controllers/$method/
        } else {
            if ($query = $this->main_model->get_content($method)) {
                $data['content'] = $query[0]->text;
                // it shows at views/main.php
            } else {
                show_404($method);
            }
        }
        $data['main_content'] = 'main';
        $this->load->view('includes/template', $data);
    }

}

再次更新(routes.php):所以,看起来就像我搜索的内容(工作示例):

$route['default_controller'] = "main";
$route['404_override'] = '';


$subfolders = glob(APPPATH.'controllers/*', GLOB_ONLYDIR);

foreach ($subfolders as $folder) {
    $folder = preg_replace('/application\/controllers\//', '', $folder);
    $route[$folder] = $folder.'/main/index/';
    $route[$folder.'/(:any)'] = $folder.'/main/$1';
}

$route['(:any)'] = 'main/index/$1';

但是,完全需要这样的一些:

http://example.com/1/2/3/4/5/6/...

  1. 文件夹“控制器”有子文件夹“1”?
  2. 是:文件夹“1”有子文件夹“2”?
  3. 否:文件夹“1”有控制器“2.php”?
  4. 否:控制器“controllers/1/main.php”具有功能“2”?
  5. 是:重定向到 http://example.com/1/2/ - 其中 3,4,5 - 参数..

当你有这样的结构时,这真的很好:

http://example.com/blog/ - recent blog's posts
http://example.com/blog/2007/ - recent from 2007 year blog's posts
http://example.com/blog/2007/06/ - same with month number
http://example.com/blog/2007/06/29/ - same with day number
http://example.com/blog/web-design/ - recent blog's post's about web design
http://example.com/blog/web-design/2007/ - blog' posts about web design from 2007 years.
http://example.com/blog/current-post-title/ - current post

我发现同样有趣http://codeigniter.com/forums/viewthread/97024/#490613

4

3 回答 3

3

我没有仔细阅读您的问题,但这立即引起了我的注意:

if (is_dir($path . '/' . $folder)) {
    echo "$route['$folder/(:any)'] = '$folder/index/$1';"; //<---- why echo ???
}

老实说,我不确定为什么除了不起作用之外,这还没有给您带来严重的问题。

您不想echo在这里路由,它只会尝试将字符串打印到屏幕上,甚至不会以这种方式解释为 PHP。引号也有一些问题需要纠正,以便可以将变量读取为变量,而不是字符串。试试这个:

if (is_dir($path . '/' . $folder)) {
    $route[$folder.'/(:any)'] = $folder.'/index/$1';
}

旁白:我想提供一些与您的问题没有直接关系的额外资源,但应该可以帮助您解决问题:

于 2011-08-07T23:36:30.477 回答
1

很难说为什么您的路线注册失败。从您的代码中,我可以看到您没有注册路由(您只是回显它们),另外我看到字符串中变量的使用不一致。可能你有点混淆了,关于路由的 codeigniter 文档也不是很精确(在一些小问题上,他们的代码示例在语法上并不是真正正确的,但总的来说它很好)。

我建议您首先移动逻辑以将您的动态路由注册到它自己的函数中。这将使事情更加模块化,您可以更轻松地更改事情,并且不会用变量污染全局命名空间。

基于此,我对您的代码进行了一些重构。这并不意味着这有效(未经测试),但是当您阅读它时它可能会使事情变得更清楚:

function register_dynamic_routes($path, array &$route)
{
    $nodes = scandir($path);
    if (false === $nodes)
    {
        throw new InvalidArgumentException(sprintf('Path parameter invalid. scandir("$path") failed.', $path));
    }

    foreach ($nodes as $node)
    {
        if ($node === '.' or $node === '..')
            continue
            ;

        if (!is_dir("{$path}/{$node}")
            continue
            ;

        $routeDef = "{$folder}/(:any)";
        $routeResolve = "{$folder}/index/\$1";
        $route[$routeDef] = $routeResolve;

        # FIXME debug output
        echo "\$route['{$routeDef}'] = '{$routeResolve}';";
    }
}

$path = APPPATH.'controllers/';
register_dynamic_routes($path, $route);
$route['(:any)'] = 'main/index/$1';

在此旁边,您可能不想将所有内容都转移到index动作上,而是转移到动作dynamic上。此外,您可能希望拥有一个将所有内容委托给子控制器的基本控制器,而不是为每个控制器添加路由。但这取决于你。上面的示例基于您在问题中概述的目录方法。

编辑:URI 路由部分旁边的控制器部分中提供了其他信息

于 2011-08-07T19:47:15.437 回答
0

这一切似乎有点复杂。

另外,如果您在数据库中有数百(或数千或更多?)可能的路由,您可能不希望每次在应用程序中加载任何页面时都将它们全部加载到“$routes”数组中。

相反,为什么不这样做呢?

routes.php 的最后一行:

$route['404_override'] = 'vanity';

控制器文件:Vanity.php:

<?php
 defined('BASEPATH') OR exit('No direct script access allowed');

class Vanity extends MY_Controller {

/**
 * Vanity Page controller.
 *
 */

public function __construct() {
    parent::__construct();
}


public function index()
{
    $url = $_SERVER['PHP_SELF'];
    $url = str_replace("/index.php/", "", $url);

    // you could check here if $url is valid. If not, then load 404 via:
    //
    //  show_404();
    //
    // or, if it is valid then load the appropriate view, redirect, or
    // whatever else it is you needed to do!


    echo "Hello from page " . $url;
    exit;



}


}


?>
于 2015-11-09T21:02:05.953 回答