如何路由相同的Codeigniter控制器

时间:2012-09-29 11:43:47

标签: php codeigniter routing controller remap

我的Codeigniter项目有很多相同的类别,每个类别都有许多相同的方法。

为了使它更动态和更清洁,我使用_remap函数在控制器中加载相同的方法。现在我正在尝试复制控制器

e.g。我的控制器 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 **/

重新映射对于Antelope及其所有重映射方法都可以正常工作,但有没有办法让我将同样的方法应用于所有其他文件所以我只能拥有一个Animal.php控制器文件

我想我可能会使用routes.php,但是控制器列表太长了;如果我明确列出每个“动物”路由,我会在路径文件中有数百行。

有什么方法吗?

编辑:“动物类型”列在数据库中,并会随着时间的推移而不断增加。我不想继续重新审视项目来创建新的控制器或为数据库中的新元素添加新类!这就是我想使用动态路由方法的原因。此外,该项目是网站重新设计,因此像http://www.website.com/antelope/buy/3这样的网址需要保持不变。

3 个答案:

答案 0 :(得分:4)

诀窍是要意识到动物类型是可变的,并且您正在尝试将其映射到静态文件。 不要这样做。只需将动物作为索引函数的第一个参数传递。这就是参数的用途:变量。

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

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

设置单一路线:

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

现在,如果你前往http://localhost/yourapp/animal/antelope

CodeIgniter会回应“我是羚羊!”

评论后编辑:

CodeIgniter在路由文件中从上到下进行,并在找到有效文件时中断。您可以将其放在config/routes.php文件的底部

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

您需要在此之上重新路由所有其他控制器。

答案 1 :(得分:1)

您可以尝试的几个选项是:

  1. 拥有一个Animals.php基类并继承所有其他类别
  2. Animal.php

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

    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 
    } 
    

    这个方法需要你有100个几乎空白的控制器文件(每个动物/类别一个),所以是和非动态的,但是允许你在Animal基类中实现__init()方法并覆盖它子类,允许您设置类别中的任何偏差(即腿数等)


    1. 为所有动物使用一条路线
    2. 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

      <?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 **/
      

      这有点动态,因为您可以从数据库加载有效动物列表,但网址不会像http://www.sample.com/bat/sell vs http://www.sample.com/animal/bat/sell

      一样干净

答案 2 :(得分:1)

只需创建一个继承自

的类
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
    }
}