php - 正则表达式非 - Codeigniter路由正则表达式-在控制器/方法名称中使用短划线




正则表达式至少出现一次 (6)

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

例如URL

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

会路由到

/controller_name/method_name_which_is_long/

请参阅: http://codeigniter.com/forums/viewreply/696690/http://codeigniter.com/forums/viewreply/696690/这给了我一个问题:)


升级到CodeIgniter 2之后回到这个问题。这是一个比接受的答案更强大的解决方案,因为它将在CodeIgniter核心更新中存活。

<?php
class MY_Router extends CI_Router
{ 
    public function set_class($class) 
    {
        parent::set_class($this->_repl($class));
    }

    public function set_method($method) 
    {
        parent::set_method($this->_repl($method));
    }

    public function _validate_request($segments)
    {
        if (isset($segments[0]))
            $segments[0] = $this->_repl($segments[0]);
        if (isset($segments[1]))
            $segments[1] = $this->_repl($segments[1]);

        return parent::_validate_request($segments);
    }

    private function _repl($s)
    {
        return str_replace('-', '_', $s);
    }
}

它应该保存为application/core/MY_Router.php 。 现在,您可以在控制器和方法名称中包含下划线,例如Abc_Def (在文件abc_def.php ),并使用URL /abc-def引用它们。


实际上这在Codeigniter 3中是原生的,只需在路径文件中执行此操作即可

   $route['translate_uri_dashes'] = TRUE;

它将自动为控制器和方法执行此操作。
请将此答案投票,因为它是最新的


我不确定你是否可以用路线做到这一点......

但是,在Codeigniter核心库(可能是路由器或URI)中的某个位置会将强调的uris转换为camelcase类名。

我快速查看并找不到它,但如果你这样做,只需将该库复制到你的应用程序/库文件夹,然后在那里修改它。


我相信你要找的是一个预系统或者一个预控制器hook ,它将获取所请求的URI并更新它。


这也是我的要求,我正在使用类似的路线

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

在我之前的项目中,我需要创建300-400个路由规则,其中大多数是由于强调转换为下划线。

对于我的下一个项目,我急切地希望避免它。 我做了一些快速入侵并测试了它,虽然没有在任何实时服务器中使用,它为我工作。 请执行下列操作..

确保您的system / 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;
    }

    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等网址,它会通过自动将短划线转换为下划线来调用正确的控制器和功能。

编辑:这是我们的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 $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定义为$config['subclass_prefix'] = 'MY_'; 在application / config / config.php中

方法_validate_request()添加了_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);
}

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


这是一个老问题,但我想发帖说e-mike对这个问题有很好的解决方案,而且更简单。

<?php
    public function _set_request($segments){
        // Fix only the first 2 segments
        for($i = 0; $i < 2; ++$i){
            if(isset($segments[$i])){
                $segments[$i] = str_replace('-', '_', $segments[$i]);
            }
        }

        // Run the original _set_request method now, giving it our newly replaced segments
        parent::_set_request($segments);
    }
?>

希望这可以帮助其他人解决这个问题。





routes