0

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

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

例如,我的控制器 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这样的 URL需要保持不变。

4

3 回答 3

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

您需要重新路由高于此的所有其他控制器。

于 2012-09-29T17:44:48.727 回答
1

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

  1. 有一个 Animals.php 基类并像这样继承所有其他类别

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

路由.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';

动物.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 **/

这有点动态,因为您可以从数据库中加载有效动物的列表,但 URL 不会像http://www.sample.com/bat/sellhttp://www.sample一样干净.com/animal/bat/sell

于 2012-09-29T12:11:28.650 回答
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
    }
}
于 2012-09-29T12:13:03.297 回答