关于YII AR 动态表(分表)的情况的想法 [ 新手入门 ]
在项目中很难不会遇到分表分库的情况,但是有时候想如果能够不通过建立model而使用YII AR 中的一些方法是不是很方便呢???
首先,我们想不建立表对应的model,那么我们就得将表明传进AR类中,让人兴奋的是YII在model中可以传入表名。
<?php
/**
*
* 动态表处理
* @author miliguy
*
*/
class MAR extends CActiveRecord {
public static $tableName;
public function __construct($table_name = '') {
if ($table_name === null) {
parent::__construct ( null );
} else {
self::$tableName = $table_name;
parent::__construct ();
}
}
public static function model($table_name = '', $className = __CLASS__) {
self::$tableName = $table_name;
return parent::model ( $className );
}
public function tableName() {
return self::$tableName;
}
}
首先建立一个MAR是我自己的AR 继承YII的CAR类,然后建立一个公用的model,让其他不建立model的表都走这个model,代码如下:
<?php
/**
*
* 一些小表不建立自己的model,将使用这个公共的model
* @author miliguy
*
*/
class Models extends MAR{
public function __construct($tableName){
parent::__construct($tableName);
}
public static function model($tableName,$className=__CLASS__){
return parent::model($tableName,$className);
}
/**
* @return string the associated database table name
*/
public function tableName()
{
return parent::$tableName;
}
}
这样在调用的时候,直接这样调用 $Model = new Models($table_name)
或者 Models::model($table_name)
然后CAR 提供的各种方法我们都可以直接进行调用了。
到此以为成功了,但是这样会遇到一个问题,这个问题是因为YII的AR实例化缓存机制造成的。AR中缓存各个实例的是一个私有的静态的数组 $_models,这个数组是以类名作为键名的,问题就出在这了。因为我们的类名都是Models这个类,所以当你在一个controller中实例化两次那个Models,永远使用的是最开始的那个实例,这样我们前面的工作就算白做了。
现在的解决方案是有两个,其中都会对CAR类进行简单修改。现放一种方案,在CAR类中添加这个方法:
/**
*
* 销毁AR实例的缓存,以适应多表在同一个控制器中调用的请款
* @param string $name
* @author miliguy
* 2012-5-23
*/
protected function unsetModels($name){
if(isset(self::$_models[$name]))
unset(self::$_models[$name]);
}
在models类中添加这个方法:
public function usetModels($name=__CLASS__)
{
parent::unsetModels($name);
}
在controller中调用的时候这样调用:
$model = new Models('post_topic_user_0');
$model->usetModels();
$model = new Models('post_topic_user_1');
这种方式会修改CAR类,不是太完美的方式。但是用着很HAppy
miliguy
注册时间:2012-04-19
最后登录:2014-08-12
在线时长:0小时0分
最后登录:2014-08-12
在线时长:0小时0分
- 粉丝1
- 金钱35
- 威望0
- 积分35