★わ浪漫少帅 发表于 2013-11-14 12:05:46

将Codeigniter的MVC变成可切换的VC或者MVC(原创)

我想有些童鞋经常会因为在Codeigniter中写一些重复的model而烦扰吧,或者这些model只是为了跟数据库打交道而写,因为Codeigniter是一个MVC架构,如果在Controller中就能自动加载想要的model而无需在models文件夹写model那岂不是方便吗?
因此我将Codeigniter的MVC架构改成了VC架构,接下来我将详细讲解过程:
第一步:在application/config/config.php中最后一行加入二句配置参数:

$config['auto_model'] = 'AUTO';
$config['default_base_model'] = 'MY_Model';
配置参数的作用接下来我会将.

第二步:打开system/core/Controller.php文件,修改构造函数添加一句$this->_init_load_model()方法:
public function __construct()
        {
                self::$instance =& $this;
               
                // Assign all the class objects that were instantiated by the
                // bootstrap file (CodeIgniter.php) to local class variables
                // so that CI can run as one big super object.
                foreach (is_loaded() as $var => $class)
                {
                        $this->$var =& load_class($class);
                }

                $this->load =& load_class('Loader', 'core');

                $this->load->initialize();

                $this->_init_load_model();
               
                log_message('debug', "Controller Class Initialized");
        }

第三步:这也是核心步骤,在system/core/Controller.php添加关键的两个函数

/**
   * You can control the $auto_model config.php to control whether to automatically load model
   */
    protected function _init_load_model()
    {
      static $_class;
      $class = self::$instance->router->class;
      if (isset($_class))
      {
              return $this->{$class} = $_class;
      }
      if ( ! class_exists('CI_Model'))
                {
                        load_class('Model', 'core');
                }
      switch ($this->config->item('auto_model')) {
              case 'AUTO':
                    $this->{$class} = $this->model($class);
                        break;
               
            default:
                $this->{$class} = $this->load->model($class.'_model');
                  break;
      }
      $_class =& $this->{$class};
    }

    function model($class)
    {
      if ( ! class_exists('CI_Model'))
       {
          load_class('Model', 'core');
       }
      $model = ucfirst($class).'_Model';
      $base_model = $this->config->item('default_base_model');
      $db = isset($this->_db) ? $this->_db : 'default';
      $id = isset($this->id) ? $this->id : 'id';
            $tmp_class =
            <<<EOT
            class {$model} extends {$base_model}{
                  public function __construct() {
                            \$this->_db = '{$db}';
                            \$this->primary_key = '{$id}';
                            parent::__construct();
                  }
            }
EOT;
      eval($tmp_class);
      return new $model();
    }
第四步:在application\core中添加一个MY_Model.php的文件重构CI Model,大家直接负责我附件中的MY_Model过去就可以了
第五版(测试):看到application\controllers\welcome.php在里面默认加入两个测试方法
//如果使用database.php的默认数据库,则不用写该构造函数
    /*function __construct()
    {
       //默认使用的database
      $this->_db = '';
       //当前table的键值
      $this->primary_key = 'id';
      parent::__construct();
    }*/
//默认已经加载当前控制器的model
    public function model(){
      $data = $this->welecome
            ->select('*')
            ->join('example2', 'welecome.id = example2.id')
            ->get_all();
      var_dump($data);
    }
//加载其他model层的时候
    public function model2(){
      $data = $this->model('example2')->get_all();
         var_dump($data);
    }

这样子在你写的controller中可以实现跨库操作,并且实现了真正的codeingiter的VC架构,
慢点,万一我还想用MVC架构怎么办?
嗯,现在你在application/config/config.php加入的配置就起了作用了
$config['auto_model'] = ''的时候这个时候就可以使用以前的方式做了,但是,控制器还是会默认帮你加载当前controller中的model,如果你想使用的话可以用$this->控制器名称后面跟sql语句去操作,看model方法即可.
$config['default_base_model']这个配置是你在application\core重载model的名称。现在可以开始你的旅程了...



MYCODEIGNITER 发表于 2013-11-14 14:34:17

不错。。顶一下

as3291363 发表于 2013-11-14 15:33:28

騷年可以呀...寫的很好
页: [1]
查看完整版本: 将Codeigniter的MVC变成可切换的VC或者MVC(原创)