无法访问子文件夹中的控制器

时间:2014-05-23 21:45:05

标签: php apache .htaccess codeigniter mod-rewrite

正如我之前的question所述,通过使用像myproject-local.com/admin/index这样的网址,我可以设法解决这个问题。 但是现在我添加了另一个控制器,比如管理员目录中的类别,当我转到myproject-local.com/admin/category时,它会给我404

routes.php文件

$route['default_controller'] = "welcome";
$route['admin/(:any)'] = "admin/admin/$1";
$route['404_override'] = '';

的.htaccess

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>

<IfModule !mod_rewrite.c>

  ErrorDocument 404 /index.php
</IfModule>

我在config.php中设置了$config['index'] = '';

3 个答案:

答案 0 :(得分:2)

即使使用路线似乎是正确的方法,我发现为每个新控制器添加路线非常烦人。

作为一个更稳定的解决方案,您可以通过扩展核心locate()类的Router方法,将多级控制器子文件夹的功能引入CodeIgniter。这是我的扩展HMVC路由器类。如果你没有使用HMVC,你可能需要编写自己的fork,稍作修改。该代码评论很好,通读,如果您有任何问题,请告诉我。

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

// Load HMVC Router
require APPPATH . 'third_party/MX/Router.php';

// ------------------------------------------------------------------------

/**
 * Better HMVC Router for CodeIgniter.
 *
 * @package     CodeIgniter
 * @author      Sepehr Lajevardi <me@sepehr.ws>
 * @copyright   Copyright (c) 2011 Sepehr Lajevardi.
 * @license     http://codeigniter.com/user_guide/license.html
 * @link        https://github.com/sepehr/ci-mx-router
 * @version     Version 1.0
 * @filesource
 */

// ------------------------------------------------------------------------

/**
 * HMVC Router extension to support multilevel controller subfolders.
 *
 * @package     CodeIgniter
 * @subpackage  Libraries
 * @category    Libraries
 * @author      Sepehr Lajevardi <me@sepehr.ws>
 * @link        https://github.com/sepehr/ci-mx-router
 */
class MY_Router extends MX_Router {

    /**
     * Routes URI segments to the proper module/app controller.
     *
     * It's a override of MX_Router's locate() method
     * to support multilevel controller subfolders.
     *
     * @param  array $segments URI segments
     * @return array
     */
    public function locate($segments)
    {
        $this->module = $this->directory = '';
        $ext = $this->config->item('controller_suffix') . EXT;

        // Use module route if available
        if (isset($segments[0]) AND $routes = Modules::parse_routes($segments[0], implode('/', $segments)))
        {
            $segments = $routes;
        }

        // Get the segments array elements
        list($module, $directory, $controller) = array_pad($segments, 3, NULL);

        // ------------------------------------------------------------------------
        // 1. Check modules (recursive)
        // ------------------------------------------------------------------------
        foreach (Modules::$locations as $location => $offset)
        {
            // Module controllers/ exists?
            if (is_dir($source = $location . $module . '/controllers/'))
            {
                $this->module    = $module;
                $this->directory = $offset . $module . '/controllers/';

                // Temporary helper variables
                $base_directory = $this->directory;
                $segments_copy  = array_slice($segments, 1);

                do {
                    // Update directory, if not in the first round
                    if (isset($segments_copy[0]) AND $directory !== $segments_copy[0])
                    {
                        $this->directory  = $base_directory . $directory . '/';
                        $directory       .= '/' . $segments_copy[0];
                    }

                    // Check if controller file exists
                    if ($directory AND is_file($source . $directory . $ext))
                    {
                        return $segments_copy;
                    }

                    // Move forward through the segments
                    $segments_copy = array_slice($segments_copy, 1);
                }
                while ( ! empty($segments_copy) AND $directory AND is_dir($source . $directory . '/'));

                // Check for default module-named controller
                if (is_file($source . $module . $ext))
                {
                    $this->directory = $base_directory;
                    return $segments;
                }
            }
        } // foreach

        // ------------------------------------------------------------------------
        // 2. Check app controllers in APPPATH/controllers/
        // ------------------------------------------------------------------------
        if (is_file(APPPATH . 'controllers/' . $module . $ext))
        {
            return $segments;
        }

        // Application sub-directory controller exists?
        if ($directory AND is_file(APPPATH . 'controllers/' . $module . '/' . $directory . $ext))
        {
            $this->directory = $module . '/';
            return array_slice($segments, 1);
        }

        // ------------------------------------------------------------------------
        // 4. Check multilevel sub-directories in APPPATH/controllers/
        // ------------------------------------------------------------------------
        if ($directory)
        {
            $dir = '';

            do {
                // Go forward in segments to check for directories
                empty($dir) OR $dir .= '/';
                $dir .= $segments[0];

                // Update segments array
                $segments = array_slice($segments, 1);
            }
            while (count($segments) > 0 AND is_dir(APPPATH . 'controllers/' . $dir . '/' . $segments[0]));

            // Set the directory and remove it from the segments array
            $this->directory = str_replace('.', '', $dir) . '/';

            // If no controller found, use 'default_controller' as defined in 'config/routes.php'
            if (count($segments) > 0
                AND ! file_exists(APPPATH . 'controllers/' . $this->fetch_directory() . $segments[0] . EXT))
            {
                array_unshift($segments, $this->default_controller);
            }
            else if (empty($segments) AND is_dir(APPPATH . 'controllers/' . $this->directory))
            {
                $segments = array($this->default_controller);
            }

            if (count($segments) > 0)
            {
                // Does the requested controller exist in the sub-folder?
                if ( ! file_exists(APPPATH . 'controllers/' . $this->fetch_directory() . $segments[0] . EXT))
                {
                    $this->directory = '';
                }
            }

            if ($this->directory . $segments[0] != $module . '/' . $this->default_controller
                AND count($segments) > 0
                AND file_exists(APPPATH . 'controllers/' . $this->fetch_directory() . $segments[0] . EXT ) )
            {
                return $segments;
            }
        }

        // ------------------------------------------------------------------------
        // 5. Check application sub-directory default controller
        // ------------------------------------------------------------------------
        if (is_file(APPPATH . 'controllers/' . $module . '/' . $this->default_controller . $ext))
        {
            $this->directory = $module . '/';
            return array($this->default_controller);
        }
    }

    // ------------------------------------------------------------------------

}
// End of MY_Router class

/* End of file MY_Router.php */
/* Location: ./application/core/MY_Router.php */

希望它有所帮助。

答案 1 :(得分:1)

试试这种方式

$route['default_controller'] = "welcome";
$route['admin/category/(:any)'] = "admin/category/$1";
$route['admin/(:any)'] = "admin/admin/$1";
$route['404_override'] = '';

答案 2 :(得分:0)

如果发现我是否使用hmvc和路由,那么HMVC一切正常。因为这是我使用hmvc路由的方式,如果下载最新版本,你必须在路由中包含功能,如下所示。无需为路由中的hmvc添加其他脚本,只需使用他们拥有的内容。

$route['default_controller'] = "folder/file/index"; //Works
$route['404_override'] = '';
$route['some_controller_name_a'] = "folder/file/index"; //Works
$route['some_controller_name_b'] = "folder/file/yourfunction"; //Works

//My Way


$route['default_controller'] = "install/common/step_1/index";
$route['404_override'] = '';

// If default controller does not work with sub folder add it like so then should work.

$route['step_1'] = "install/common/step_1/index";
$route['step_2'] = "install/common/step_2/index";
$route['step_3'] = "install/common/step_3/index";
$route['step_4'] = "install/common/step_4/index";

如果使用重定向可以使其像重定向一样(&#39; some_controller_name_a&#39;);作品

使用

Options +FollowSymLinks
Options -Indexes
DirectoryIndex index.php
RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]

同时从应用程序

中的配置文件中删除index.php

同样在视图文件加载控制器

<?php echo Modules::run('install/common/header/index');?>