Unable to access the controller in subfolder

2019-08-03 00:10发布

问题:

As stated in my previous question, I some how managed to cop up with this one, by using the URL like myproject-local.com/admin/index But now I have added another controller, say category in admin directory and when I go to myproject-local.com/admin/category, it gives me 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>

and I have set $config['index'] = ''; in my config.php

回答1:

Try this way

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


回答2:

Even though that using routes seems to be the right n' easy way to go I found it so annoying to add a route for each new controller.

As a more stable solution to this you can bring the feature of multi-level controller subfolders to CodeIgniter by extending the locate() method of core Router class. Here is my extended HMVC router class. If you're not using HMVC, you might need to write your own fork with a little modification. The code is well commented, read through and let me know if you have any questions.

<?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 */

Hope it helps.



回答3:

If find if I use hmvc with routes it all works fine with HMVC. Because this is way I use it with hmvc routes if download latest version you must include the function in route like shown below. No need to add other script for hmvc in the route only use what they have.

$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";

And if use redirect can make it like redirect('some_controller_name_a'); Works

Use

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]

Also remove the index.php from config file in application

Also on the view file load controller

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