Codeigniter路由正则表达式 - 在控制器/方法名称中使用破折号 [英] Codeigniter Routes regex - using dashes in controller/method names

查看:293
本文介绍了Codeigniter路由正则表达式 - 在控制器/方法名称中使用破折号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



例如URL

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

将路由到

  / controller_name / method_name_which_is_long / 

请参阅: http://codeigniter.com/forums/viewreply/696690/ ,这让我想起:)

解决方案

这也是我的要求,我使用像

这样的路由

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

在我之前的项目中,我需要创建300-400个路由规则,以强调转换。



对于我的下一个项目,我迫切希望避免它。我做了一些快速黑客和测试,虽然没有使用在任何活的服务器,它为我工作。请执行以下操作。



确保您的系统/ application / config / config.php

中的subclass_prefix如下所示

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

然后在system / application / libraries目录中上传名为MY_Router.php的文件。

 <?php 

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

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

function _validate_request($ segments)
{
//请求的控制器是否存在于根文件夹中?
if(file_exists(APPPATH.'controllers /'。str_replace(' - ','_',$ segments [0])。EXT))
{
return $ segments;
}
//控制器是否在子文件夹中?
if(is_dir(APPPATH.'controllers /'.$ segments [0]))
{
//设置目录并从段数组中删除它
$ this- > set_directory($ segments [0]);
$ segments = array_slice($ segments,1);

if(count($ segments)> 0)
{
//请求的控制器是否存在于子文件夹中?
if(!file_exists(APPPATH.'controllers /'.$ this-> fetch_directory()。str_replace(' - ','_',$ segments [0])。
show_404($ this-> fetch_directory()。$ segments [0]);
}
}
else
{
$ this-> set_class($ this-> default_controller);
$ this-> set_method('index');

//默认控制器是否存在于子文件夹中?
if(!file_exists(APPPATH.'controllers /'.$ this-> fetch_directory()。$ this-> default_controller.EXT))
{
$ this->目录='';
return array();
}

}

return $ segments;
}

//找不到所请求的控制器...
show_404($ segments [0]);
}
}

现在你可以自由地使用 http://example.com/logued/presse-access ,它将自动调用适当的控制器和函数


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

 <?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 $段;
}

//请求的控制器是否存在于根文件夹中?
if(file_exists(APPPATH.'controllers /'。str_replace(' - ','_',$ segments [0])。'。php'))
{
return $ segments ;
}

//控制器是否在子文件夹中?
if(is_dir(APPPATH.'controllers /'.$ segments [0]))
{
//设置目录并从段数组中删除它
$ this- > set_directory($ segments [0]);
$ segments = array_slice($ segments,1);


while(count($ segments)> 0&& is_dir(APPPATH.'controllers /'.$ this-> directory。$ segments [0]))
{
//设置目录并将其从段数组中删除
$ this-> set_directory($ this-> directory。$ segments [0]);
$ segments = array_slice($ segments,1);
}

if(count($ segments)> 0)
{
//请求的控制器是否存在于子文件夹中?
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']);

$ it-> 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
{
//方法是在路由中指定的吗?
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');
}

//默认控制器是否存在于子文件夹中?
if(!file_exists(APPPATH.'controllers /'.$ this-> fetch_directory()。$ this-> default_controller。'。php'))
{
$ this- > directory ='';
return array();
}

}

return $ segments;
}


//如果我们得到这么远,这意味着URI不与有效的
//控制器类相关联。我们现在看看是否有一个覆盖
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;
}


//此时没有其他操作,但显示一个404
show_404($ segments [0]);
}
}

现在必须将此文件放置为application / core /MY_Router.php并确保他的subclass_prefix在application / config / config.php

中定义为 $ config ['subclass_prefix'] ='MY _';

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

  while(count($ segments)> 0&& is_dir(APPPATH.'controllers /'.$ this-> directory。$ segments [0]))
{
//设置目录并将其从段数组中删除
$ this-> set_directory($ this-> directory。$ segments [0]);
$ segments = array_slice($ segments,1);
}

使用它可以使用控制器内的多级子目录目录,而通常我们可以在控制器文件夹中使用单级子目录,并可以在URL中调用它。如果没有必要,可以删除此代码,但对正常流程没有损害。


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

For example the URL

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

would route to

/controller_name/method_name_which_is_long/

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

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..

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

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

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]);
    }
}

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.

Edit: 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]);
    }
}

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

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);
}

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.

这篇关于Codeigniter路由正则表达式 - 在控制器/方法名称中使用破折号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆