为控制器中的操作方法添加路由


Add Routes for Action Method in Controller

在.NET中,使用AttributeRouting,我们可以为每个Action Method添加Route。低于

[HttpGet, Route("Create-Project")]
public ActionResult CreateProject()
{
     return View();
}

所以,在上面的代码中。。。第1行表示我们可以提到每个Action Method的路由。所以url会变成下面的样子。。

http://domainname/Create-Project

问题

它在PHP MVC CI中可行吗?现在我必须在config文件夹中的route.php中编写代码。

routes.php中,您可以将其定义为


语法

$route['short_url_name'] = 'complete/path/for/url';

示例

$route['Contact-Us'] = 'home/contact';
$route['Blog'] = 'home/blog';
$route['Our-Work'] = 'home/work';

所以URL看起来像

http://domain.com/Contact-Us
http://domain.com/Blog
http://domain.com/Our-Work

Codeigner.com示例

Application/config/router.php中,您可以添加一些类似的配置:

$route['Create-Project'] = 'home/welcome';

所以,每次访问http://domain.com/Create-Project,它会将您重定向到http://domain.com/home/welcome

如果你正在寻找数据库驱动的动态路由,你可以这样做,否则你可以遵循@abdulla的建议。

动态路由的表结构(表名示例:路由)。

id    | slug    |route
---------------------------------------------
1     |Pankaj   |controller/method/id of user
2     |Abdulla  |controller/method/id of user
3     |Niranjan |controller/method/id of user

控制器内

$this->load->helper('text');
$slug = $this->input->post("username");// example if you want the username in url as route.
$slug = url_title(convert_accented_characters($slug), 'dash', TRUE);
$slug = $this->Routes_model->validate_slug($slug);
$route['slug'] = $slug;
$route_id = $this->Routes_model->save($route);

$route_id将在routes表中具有路由id,在users table中插入路由id和段塞(对于哪个表,您想要动态路由)

这是路线模型的代码

<?php
class Routes_Model extends CI_Model {
    var $file_name; 
    function __construct()
    {
        parent::__construct();
        $this->file_name = APPPATH.'config/routes'.EXT;
    }
    function check_slug($slug, $id=false)
    {
        if($id)
        {
                $this->db->where('id !=', $id);
        }
        $this->db->where('slug', $slug);
        return (bool) $this->db->count_all_results('routes');
    }
    function validate_slug($slug, $id=false, $count=false)
    {
            if(is_numeric($slug))
            {
               $slug = '';
               $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
                for ($i = 0; $i < 3; $i++) 
                {
                        $slug .= $characters[rand(0, strlen($characters) - 1)];
                }
            }
            if($this->check_slug($slug.$count, $id))
            {
                    if(!$count)
                    {
                            $count  = 1;
                    }
                    else
                    {
                            $count++;
                    }
                    return $this->validate_slug($slug, $id, $count);
            }
            else
            {
                    return $slug.$count;
            }
    }
    function save($route)
    {
//        print_r($route);exit;
            if(!empty($route['id']))
            {
                    $this->db->where('id', $route['id']);
                    $this->db->update('routes', $route);
                    return $route['id'];
            }
            else
            {
                    $this->db->insert('routes', $route);
                    return $this->db->insert_id();
            }
    }
}
?>

我检查过的一个条件是,如果用户名是一个数字,我将在validate_slug()中生成3个字符的长度。

现在按文件名MY_Router.phpcore文件夹中添加以下代码

    <?php
    class My_Router extends CI_Router 
    {
            function __construct()
            {
                    parent::__construct();
            }
            // this is here to add an additional layer to the routing system.
            //If a route isn't found in the routes config file. then it will scan the database for a matching route.
            function _parse_routes()
            {
                    $segments   = $this->uri->segments;
                    $segments   = array_splice($segments, -2, 2);
                    // Turn the segment array into a URI string
                    $uri = implode('/', $segments);
                    // Is there a literal match?  If so we're done
                    if (isset($this->routes[$uri]))
                    {
                            return $this->_set_request(explode('/', $this->routes[$uri]));
                    }
                    // Loop through the route array looking for wild-cards
                    foreach ($this->routes as $key => $val)
                    {
                            // Convert wild-cards to RegEx
                            $key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key));
                            // Does the RegEx match?
                            if (preg_match('#^'.$key.'$#', $uri))
                            {
                                    // Do we have a back-reference?
                                    if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE)
                                    {
                                            $val = preg_replace('#^'.$key.'$#', $val, $uri);
                                    }
                                    return $this->_set_request(explode('/', $val));
                            }
                    }
                    //look through the database for a route that matches and apply the same logic as above :-)
                    //load the database connection information
                    require_once BASEPATH.'database/DB'.EXT;
                    if(count($segments) == 1)
                    {
                            $row    = $this->_get_db_route($segments[0]);
                            if(!empty($row))
                            {
                                    return $this->_set_request(explode('/', $row['route']));
                            }
                    }
                    else
                    {   
                            $segments   = array_reverse($segments);
                            //start with the end just to make sure we're not a multi-tiered category or category/product combo before moving to the second segment
                            //we could stop people from naming products or categories after numbers, but that would be limiting their use.
                            $row    = $this->_get_db_route($segments[0]);
                            //set a pagination flag. If this is set true in the next if statement we'll know that the first row is segment is possibly a page number
                            $page_flag  = false;
                            if($row)
                            {
                                    return $this->_set_request(explode('/', $row['route']));
                            }
                            else
                            {
                                    //this is the second go
                                    $row    = $this->_get_db_route($segments[1]);
                                    $page_flag  = true;
                            }
                            //we have a hit, continue down the path!
                            if($row)
                            {
                                    if(!$page_flag)
                                    {
                                            return $this->_set_request(explode('/', $row['route']));
                                    }
                                    else
                                    {
                                            $key = $row['slug'].'/([0-9]+)';
                                            //pages can only be numerical. This could end in a mighty big error!!!!
                                            if (preg_match('#^'.$key.'$#', $uri))
                                            {
                                                    $row['route'] = preg_replace('#^'.$key.'$#', $row['route'],$uri);
                                                    return $this->_set_request(explode('/', $row['route']));
                                            }
                                    }
                            }
                    }
                    // If we got this far it means we didn't encounter a
                    // matching route so we'll set the site default route
                    $this->_set_request($this->uri->segments);
            }
            function _get_db_route($slug)
            {
                    return DB()->where('slug',$slug)->get('routes')->row_array();
            }
    }

上述文件非常重要。当codeigniter第一次在core文件夹中运行文件时,这将创建您想要的slug。无需在routes.php文件中添加任何路由。

现在,在显示用户时,您可以在users表中shud回显slug。

假设控制器名称为users,方法名称为edit_user

你的控制器代码会像这样,

function edit_user($id){
      // fetch the data related to $id, and load the view here
}

在url中,如果它看到Niranjan,它将自动从routes表中选择路由,并进入您的函数edit_user()

是的方法看起来很长,但效果很好,我在所有的电子商务网站上都使用它