Codeigniter Routes 正则表达式 - 在控制器/方法名称中使用破折号

2022-01-08 00:00:00 regex routes php codeigniter

我正在寻找一条单线路由,将虚线控制器和方法名称路由到实际的下划线控制器和方法名称.

I'm looking for a one line route to route dashed controller and method names to the actual underscored controller and method names.

例如网址

/controller-name/method-name-which-is-long/

将路由到

/controller_name/method_name_which_is_long/

参见:http://codeigniter.com/forums/viewreply/696690/给了我问的想法:)

see: http://codeigniter.com/forums/viewreply/696690/ which gave me the idea to ask :)

推荐答案

这也正是我的要求,我使用了类似的路由

That is exactly my requirement too and I was using routes like

$route['logued/presse-access'] = "logued/presse_access";

在我之前的项目中,我需要创建 300-400 条路由规则,其中大部分是由于破折号到下划线的转换.

In my previous project I needed to create 300-400 routing rules, most of them are due to dash to underscore conversion.

对于我的下一个项目,我急切地想避免它.我做了一些快速破解并对其进行了测试,虽然没有在任何实时服务器中使用过,但它对我有用.执行以下操作..

For my next project I eagerly want to avoid it. I have done some quick hack and tested it, though have not used in any live server, its working for me. Do the following..

确保 subclass_prefix 在您的 system/application/config/config.php 中如下所示

Make sure the subclass_prefix is as follows in your system/application/config/config.php

$config['subclass_prefix'] = 'MY_';

然后在system/application/libraries目录下上传一个名为MY_Router.php的文件.

Then upload a file named MY_Router.php in system/application/libraries directory.

<?php

class MY_Router extends CI_Router { 
    function set_class($class) 
    {
        //$this->class = $class;
        $this->class = str_replace('-', '_', $class);
        //echo 'class:'.$this->class;
    }

    function set_method($method) 
    {
//      $this->method = $method;
        $this->method = str_replace('-', '_', $method);
    }

    function _validate_request($segments)
    {
        // Does the requested controller exist in the root folder?
        if (file_exists(APPPATH.'controllers/'.str_replace('-', '_', $segments[0]).EXT))
        {
            return $segments;
        }
        // Is the controller in a sub-folder?
        if (is_dir(APPPATH.'controllers/'.$segments[0]))
        {       
            // Set the directory and remove it from the segment array
            $this->set_directory($segments[0]);
            $segments = array_slice($segments, 1);

            if (count($segments) > 0)
            {
                // Does the requested controller exist in the sub-folder?
                if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().str_replace('-', '_', $segments[0]).EXT))
                {
                    show_404($this->fetch_directory().$segments[0]);
                }
            }
            else
            {
                $this->set_class($this->default_controller);
                $this->set_method('index');

                // Does the default controller exist in the sub-folder?
                if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT))
                {
                    $this->directory = '';
                    return array();
                }

            }

            return $segments;
        }

        // Can't find the requested controller...
        show_404($segments[0]);
    }
}

现在您可以自由使用像 http://example.com/logued/presse-access 它将通过自动将破折号转换为下划线来调用正确的控制器和函数.

Now you can freely use url like http://example.com/logued/presse-access and it will call the proper controller and function by automatically converting dash to underscore.

这是我们的 Codeigniter 2 解决方案,它覆盖了新的 CI_Router 函数:

Here is our Codeigniter 2 solution which overrides the new CI_Router functions:

<?php

class MY_Router extends CI_Router { 
    function set_class($class) 
    {
        $this->class = str_replace('-', '_', $class);
    }

    function set_method($method) 
    {
        $this->method = str_replace('-', '_', $method);
    }

    function set_directory($dir) {
        $this->directory = $dir.'/';
    }

    function _validate_request($segments)
    {
        if (count($segments) == 0)
        {
            return $segments;
        }

        // Does the requested controller exist in the root folder?
        if (file_exists(APPPATH.'controllers/'.str_replace('-', '_', $segments[0]).'.php'))
        {
            return $segments;
        }

        // Is the controller in a sub-folder?
        if (is_dir(APPPATH.'controllers/'.$segments[0]))
        {
            // Set the directory and remove it from the segment array
            $this->set_directory($segments[0]);
            $segments = array_slice($segments, 1);


            while(count($segments) > 0 && is_dir(APPPATH.'controllers/'.$this->directory.$segments[0]))
            {
                // Set the directory and remove it from the segment array
                $this->set_directory($this->directory . $segments[0]);
                $segments = array_slice($segments, 1);
            }

            if (count($segments) > 0)
            {
                // Does the requested controller exist in the sub-folder?
                if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().str_replace('-', '_', $segments[0]).'.php'))
                {
                    if ( ! empty($this->routes['404_override']))
                    {
                        $x = explode('/', $this->routes['404_override']);

                        $this->set_directory('');
                        $this->set_class($x[0]);
                        $this->set_method(isset($x[1]) ? $x[1] : 'index');

                        return $x;
                    }
                    else
                    {
                        show_404($this->fetch_directory().$segments[0]);
                    }
                }
            }
            else
            {
                // Is the method being specified in the route?
                if (strpos($this->default_controller, '/') !== FALSE)
                {
                    $x = explode('/', $this->default_controller);

                    $this->set_class($x[0]);
                    $this->set_method($x[1]);
                }
                else
                {
                    $this->set_class($this->default_controller);
                    $this->set_method('index');
                }

                // Does the default controller exist in the sub-folder?
                if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.'.php'))
                {
                    $this->directory = '';
                    return array();
                }

            }

            return $segments;
        }


        // If we've gotten this far it means that the URI does not correlate to a valid
        // controller class.  We will now see if there is an override
        if ( ! empty($this->routes['404_override']))
        {
            $x = explode('/', $this->routes['404_override']);

            $this->set_class($x[0]);
            $this->set_method(isset($x[1]) ? $x[1] : 'index');

            return $x;
        }


        // Nothing else to do at this point but show a 404
        show_404($segments[0]);
    }
}

现在必须像 application/core/MY_Router.php 一样放置这个文件,并确保他的 subclass_prefix 在 application/config 中定义为 $config['subclass_prefix'] = 'MY_';/config.php

Now one has to place this file like application/core/MY_Router.php and make sure he has subclass_prefix is defined as $config['subclass_prefix'] = 'MY_'; in application/config/config.php

在方法_validate_request()中添加了几行额外的代码:

Few extra lines of code has been added in method _validate_request():

while(count($segments) > 0 && is_dir(APPPATH.'controllers/'.$this->directory.$segments[0]))
{
    // Set the directory and remove it from the segment array
    $this->set_directory($this->directory . $segments[0]);
    $segments = array_slice($segments, 1);
}

使用它是为了可以使用controllers目录中的多级子目录,而通常我们可以使用controllers文件夹中的单级子目录,并且可以在url中调用它.如果没有必要,可以删除此代码,但对正常流程没有危害.

It is used so that one can make use of multi-level subdirectory inside controllers directory, whereas normally we can use single level subdirectory inside controllers folder and can call it in url. One can remove this code if it not necessary but it has no harm on the normal flow.

相关文章