简体   繁体   English

如何路由相同的Codeigniter控制器

[英]How to route identical Codeigniter Controllers

My Codeigniter project has a long list of identical categories, each with many identical methods. 我的Codeigniter项目包含一长串相同的类别,每个类别都有许多相同的方法。

To make it dynamic and cleaner, I have used _remap functions to load the identical methods within the controller. 为了使其更动态,更清洁,我使用了_remap函数在控制器内加载相同的方法。 Now I am trying to replicate the controllers 现在我正在尝试复制控制器

eg My controllers Antelope.php Bat.php Cuckoo.php Dog.php Elephant.php... Zebra.php all have this format below (I used _remap to condense all the similar methods into one). 例如,我的控制器Antelope.php Bat.php Cuckoo.php Dog.php Elephant.php ... Zebra.php在下面都具有这种格式(我使用_remap将所有类似的方法压缩为一种)。

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Antelope extends CI_Controller {

    function __construct() {
        parent::__construct();
    }

    private function _remap($method, $params=array()){
       $this->animal = ucwords($this->router->fetch_class());
       $allowed_methods = array("Tame", "Buy", "Sell", "Gift");
       if (in_array($method, $allowed_methods)):
           // Model zoo has been autoloaded      
           data["foobar"] = $this->zoo->get_data($this->animal, $method);
           // Stuff goes here
       else:
          $this->index();
       endif;
    }

    public function index(){
       // Stuff goes here
    }
}

/** End of file Antelope.php **/

The remapping works fine for Antelope and all its remapped methods, but is there a way for me to apply this same method to all the other files so I can just have a single Animal.php Controller file instead ? 重新映射对于Antelope及其所有重新映射的方法都工作正常,但是有没有办法让我将相同的方法应用于所有其他文件, 因此我可以只拥有一个Animal.php控制器文件呢?

I guess I may use routes.php, but the list of Controllers is too long; 我想我可能会使用routes.php,但是控制器列表太长; I'd have hundreds of lines in the routes file if I explicitly list each "animal" routing. 如果我明确列出每个“动物”路由,则路由文件中将包含数百行。

Any way around this? 可以解决吗?

EDIT: The "animal types" are listed in a database, and will keep increasing over time. 编辑: “动物类型”在数据库中列出,并且会随着时间的推移不断增加。 I don't want to keep revisiting the project to create new controllers or add new classes for the new elements in the database! 我不想继续访问该项目以创建新的控制器或为数据库中的新元素添加新的类! This is why I want to use a dynamic routing method. 这就是为什么我要使用动态路由方法。 Also, the project is a site redesign, so the URLs like http://www.website.com/antelope/buy/3 need to remain the same. 另外,该项目是对网站的重新设计,因此http://www.website.com/antelope/buy/3之类的URL必须保持不变。

The trick is to realize that the animal type is variable and you're trying to map it to static files. 诀窍是要认识到动物的类型是可变的,并且您试图将其映射到静态文件。 Don't do this. 不要这样 Just pass the animal as the first argument to the index function. 只需将动物作为第一个参数传递给索引函数。 That's what arguments are for: variables. 这就是参数的含义:变量。

class Animal extends CI_Controller{
    function __construct(){
        parent::__construct();
    }

    function index($animal){
        echo "I'm the {$animal}!";
    }
}

And set up the single route: 并设置单条路线:

$route['animal/(:any)'] = "animal/index/$1";

Now, if you head to http://localhost/yourapp/animal/antelope 现在,如果您转到http://localhost/yourapp/animal/antelope

CodeIgniter will echo "I'm the antelope!" CodeIgniter会回声“我是羚羊!”

Edit after your comment: 评论后编辑:

CodeIgniter goes from top to bottom in your routes file and breaks when it finds a valid one. CodeIgniter在您的路由文件中自上而下,并在找到有效的文件时中断。 You can place this at the bottom of your config/routes.php file: 您可以将其放在config/routes.php文件的底部

$route['(:any)/buy/(:id)'] = "animal/$1/buy/$2";
$route[':any'] = "animal/index/$1";
//etc

You'll need to re-route all other controllers above this. 您需要在此之上重新路由所有其他控制器。

A couple of options you could try are: 您可以尝试以下几种选择:

  1. Have a Animals.php base class and inherit all other categories from that like so 有一个Animals.php基类,并像这样继承所有其他类别

Animal.php Animal.php

class Animal extends CI_Controller {
    //Your _remap() and other methods
}

Antelope.php Bat.php Cuckoo.php Dog.php Elephant.php... Zebra.php Antelope.php Bat.php Cuckoo.php Dog.php Elephant.php ... Zebra.php

require_once 'animal.php';

class Antelope extends Animal {
    //Antelope inherits its methods from Animal, so this is blank 
} 

This method would require you to have 100s of almost blank controller files (one per animal/ category) so is and not very dynamic, but would allow you to implement a __init() method in the Animal base class and override it in the sub-classes, allowing you to set-up any deviations in the categories (ie number of legs etc) 此方法将需要您有100个几乎空白的控制器文件(每个动物/类别一个),而且不是很动态,但是可以让您在Animal基类中实现__init()方法并在子类中覆盖它。类,允许您设置类别中的任何偏差(例如,腿数等)


  1. Use one route for all animals 对所有动物使用一条路线

routes.php routes.php

//default index route http://www.sample.com/animal/type
$route['animal/(:any)']  = 'animal/reroute/$1/index';

//method route http://www.sample.com/animal/type/method
$route['animal/(:any)/(:any)']  = 'animal/reroute/$1/$2';

animal.php animal.php

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Animal extends CI_Controller {

    function __construct() {
        parent::__construct();
    }


    public function index(){
       // Stuff goes here
    }

    public function reroute($animal, $method) {
       //Check the $animal is valid
       //Check the $method is valid
       //Do stuff   
    }


}

/** End of file animal.php **/

This is a little more dynamic, as you can then load a list of valid animals from a database, but the URLs will not be as clean http://www.sample.com/bat/sell vs http://www.sample.com/animal/bat/sell 这有点动态,因为您可以从数据库中加载有效动物的列表,但是URL不会像http://www.sample.com/bat/sellhttp://www.sample .com / animal / bat / sell

Just create a class to inherit from 只需创建一个要继承的类

class Animal extends CI_Controller {
   function __construct() {
        parent::__construct();
    }

    public function _remap($method, $params=array()){
       $this->animal = ucwords($this->router->fetch_class());
       $allowed_methods = array("Tame", "Buy", "Sell", "Gift");
       if (in_array($method, $allowed_methods)):
           // Model zoo has been autoloaded      
           data["foobar"] = $this->zoo->get_data($this->animal, $method);
           // Stuff goes here
       else:
          $this->index();
       endif;
    }
}

class Antelope extends Animal {
    public function index(){
       // Stuff goes here
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM