CodeIgniter default controller in a sub directory not working

前端 未结 9 1637
醉话见心
醉话见心 2020-11-29 10:15

My default_controller in the routes configuration is set as \"home.php\".

I have a sub directory for my controllers, lets call it \"folder\". So if I visit http://my

相关标签:
9条回答
  • 2020-11-29 10:53

    In application/config/routes.php just add this

    $this->set_directory( "user" );
    $route['default_controller'] = 'home/index';
    

    Here, user is my folder name. Then in default controller you can call any controller that is in user folder following by function name

    0 讨论(0)
  • 2020-11-29 10:58

    Even though the question has many (and an accepted answer) I, still, would like to post mine.

    I figured out that subfolders works for regular routes. For example, I can do:

    $route['frontend/test'] = "frontend/Welcome/test";
    

    and if I visit site/frontend/test, it works as expected. The problem is getting "default_controller" to work with subfolders. For example, the following doesn't work:

    $route['default_controller'] = "frontend/Welcome/test";
    

    If we examine the URI Routing > Reserved Routes section, it says:

    You can NOT use a directory as a part of this setting!

    So we need to hack our way in. I've used Girish's approach. I've examined the system/core/Router.php and created application/core/MY_Router.php.

    At first, I thought Girish made a static change to the _set_default_controller method, that it allows only subfolders. I thought it should be dynamic and subfolder should be optional. Later, I realized that he made a case for that too, but his code has duplicate logic and I was already done with mine. So I'm posting it anyway.

    <?php
    
    class MY_Router extends CI_Router {
        
        /**
         * The default controller expects a string in the following format: "controller/method".
         * The method at the end is optional. If the method is omitted, the default method is "index".
         * 
         * Examples:
         *  * $route['default_controller'] = "Welcome";
         *  * $route['default_controller'] = "Welcome/index";
         * 
         * Both end up being routed to "Welcome/index".
         * 
         * The default controller does NOT expect a subfolder in the "controllers" folder. So the following won't work:
         *  * $route['default_controller'] = "frontend/Welcome/index"
         * 
         * To make subfolders work, _set_default_controller() needs to be modified, and that's what this MY_Router is for.
         *
         * The modification is kept to a minimum and is marked.
         */
        protected function _set_default_controller()
        {
            if (empty($this->default_controller))
            {
                show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.');
            }
            
            /* START MODIFICATION */
            
            /*
                Removing this block, as it only allows/look for "controller/method".
                // Is the method being specified?
                if (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2)
                {
                    $method = 'index';
                }
            */
            
            /*
                Instead of just checking for "controller/method", we need to also look for a subfolder.
                Because the latter operations depend on the first segment.
                So, the first thing to do is to figure out if the first segment is a folder or a class/file.
                Possible inputs:
                    "Welcome"                   -> class                -> autocomplete
                    "Welcome/index"             -> class/method
                    "frontend"                  -> folder
                    "frontend/Welcome"          -> folder/class         -> autocomplete
                    "frontend/Welcome/index"    -> folder/class/method
            */
            
            $segments = explode("/", $this->default_controller);
            $segments = array_filter($segments); // ignore leading and trailing slashes
            
            if (count($segments) > 3) {
                show_error('Invalid controller. Default controller supports only one subfolder.');
            }
            
            $method = null;
            
            // If the first segment is a folder, the second needs to be a class/file.
            if (is_dir(APPPATH.'controllers/'.$segments[0])) {
                $this->set_directory($segments[0]);
                if (!isset($segments[1])) {
                    show_error('Invalid controller. A subfolder is provided, but the controller class/file is missing.');
                }
                $class = $segments[1];
                if (isset($segments[2])) {
                    $method = $segments[2];
                }
            }
            // If the first segment is NOT a folder, then it's a class/file.
            else {
                $class = $segments[0];
                if (isset($segments[1])) {
                    $method = $segments[1];
                }
            }
            
            // If the method isn't specified, assume that it's "index".
            if (!$method) {
                $method = "index";
            }
            
            /* END MODIFICATION */
            
            if ( ! file_exists(APPPATH.'controllers/'.$this->directory.ucfirst($class).'.php'))
            {
                // This will trigger 404 later
                return;
            }
            
            $this->set_class($class);
            $this->set_method($method);
            
            // Assign routed segments, index starting from 1
            $this->uri->rsegments = array(
                1 => $class,
                2 => $method
            );
            
            log_message('debug', 'No URI present. Default controller set.');
        }
        
    }
    
    0 讨论(0)
  • 2020-11-29 11:01

    Add this line in application/config/routes.php

    $this->set_directory( "yourfoldername" );
    $route['default_controller'] = 'controller name';
    
    0 讨论(0)
  • 2020-11-29 11:07

    If you want to stay flexible you need to pass on everything after the starting folder (in application/config/config.php):

    $route['home'] = "home/whatever";
    $route['home/(:any)'] = "home/whatever/$1";
    
    0 讨论(0)
  • 2020-11-29 11:11

    If i use the following code

    $this->set_directory( "user" );
    $route['default_controller'] = 'home/index';
    

    then another route in another sub directory does not work.

    Suppose i am using sub-directory user in controller directory for default controller. but if i like to use FrontEnd sub-directory for another route,

    $this->set_directory( "FrontEnd" );
    $route['product/(:any)'] = 'product/$1';
    

    then it is not working.

    0 讨论(0)
  • 2020-11-29 11:12

    For each sub-folder in your controllers folder you must specify a default controller in routes.php. The built in $route['default_controller'] will not work for sub-folders.

    e.g: For setting the default controller for you folder sub-folder to home add the following to your /application/config/routes.php file:

    $route['folder'] = "folder/home";
    

    which means http://mysite.com/folder/ is the same as http://mysite.com/folder/home as URL.

    0 讨论(0)
提交回复
热议问题