关于框架的优化建议

浏览:1289 发布日期:2015/06/30 分类:站务建议 关键字: 建议 优化
一、field 方法建建议改扩展成能传带表名的数组,join查询非常觉见,那么在查询字段里就要写成带表名的字段,字段一多,写得就很麻烦了。所以建能把$options = array(
    'tb1'=>'id,name', 
    'tb2'=>'age, name AS newname'
);
转成:tb1.id,tb1.name,tb2.age,tb2.name AS newname 查询字段
为此,我自己在CommonModel封装了一下field方法    
    /**
     * 转换成带有表名的字段
     * $options 表名对应字段字符串
     * 示例:
     * $options = array('tb1'=>'id,name,age', 'tb2'=>'id2,name2 AS newname, age2');
     */
    
    public function field($options, $except=false){
        if(is_string($options)) return parent::field($field,$except);
        $field = '';
        foreach($options as $table => $value){
            $value = ',' . preg_replace(array('/\s\s+/', '/\s*,\s*/', '/\s(AS|as)\s/'), array(' ', ',', ' '), $value);
            $value = preg_replace(array('/\s/', '/,/'), array('` `', "`,`$table`.`"), $value);
            $field .= '`'.ltrim($value, '`,').'`,';
        }
        return parent::field(rtrim($field, ','), $except);
    }
二、D函数的优化,D函数能传入两个参数,一个模型名,一个模型层名称,模型名,同时也决定了表名。但是,有时候我们没必要写许多模型文件,因为有时候是比较零散的模型方法,我们更愿意把它们集中到一个文件中去。但是,D方法限定了一个模型指向一个表名。为此,我也改写了一个D函数/**
 * 实例化模型类 格式 [资源://][模块/]模型[.模型层名称]
 * @param string $name 资源地址
 * @return Think\Model
 */
function model($name, $table='', $prefix='', $connection=''){

    list($name, $layer) = explode('.', $name);//例如: home://index/Help.Model
    if(empty($table)) $table = basename($name);
    static $_model  =   array();
    $layer          =   $layer? : C('DEFAULT_M_LAYER');
    if(isset($_model[$name.$layer]))
        return $_model[$name.$layer];
    $class = parse_res_name($name,$layer);
    if(class_exists($class)) {
        $model = new $class($table, $prefix, $connection);
    }elseif(false === strpos($name,'/')){
        // 自动加载公共模块下面的模型
        if(!C('APP_USE_NAMESPACE')){
            import('Common/'.$layer.'/'.$class);
        }else{
            $class = '\\Common\\'.$layer.'\\'.$name.$layer;
        }
        $model = class_exists($class)? new $class($table, $prefix, $connection) : new Think\Model($table, $prefix, $connection);
    }
    $_model[$name.$layer]  =  $model;
    return $model;
}
三、join方法自动加表前缀的格式是表名大写并且两边带双底杠如:__TABLE__,我是觉得这种方式有点怪异,就像模板里调用函数时 {$time|date="y-m-d",###}一样,我觉得很怪,什么###代表当前变量,明明可以写{:date('y-m-d', $time)}的标准形式,join方法建议可以传三个参数join($join,$type='INNER', $tablePrefix='') 如果type不在合法的类型之中,则认定为表前缀,表前缀为空时,取配置参数,为null时,表示无.

四、访问的方法不存在时,就查找相应的模板文件,并实例化显示,我觉得这种特性不是我们想要的,有未知的安全隐患,我们要自己决定哪些模板可以直接显示。为此,我们可以直接在总控制器里定义一个 _empty()方法:    protected function _empty($method,$args){
    
        $static = array('aboutus','nationwide', 'fzlc', 'store', 'contact', 'hzhb', 'job', 'shzr');
        if(in_array($method, $static)){
            $this->display();
        }else{
            E(L('_ERROR_ACTION_').':'.ACTION_NAME);
        }
    
    }
五、数据分页时,首先要得到总记录数,然后使用Page类得到查询limit条件,接着进行查询。查总记录数与查分页记录的sql语句几乎是一样的。M()->where()->count() 与 M()->where()->limit()->select(); 最近,我就在想能不能提供一种解决方法,我不喜欢写两遍呀...

六、用 M('table', 'b_', 'DB2')的这种传数据库配置参数的方式之后,以后再用M('table2')无配置参数的方式时,无法还原到默认的数据库配置,查了一下源码,大概知道原因,好像把 'DB_DEPLOY_TYPE' => 0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器),改成 1就可以了,可我测试好像还是不行。我觉得不管怎么说,一个主配置,一个临时动态配置,不能说临时改了,就非要再手动变回来。
七、 create方法会处理许多事件,比如自动令牌验证,但是我遇到一个问题,就是我自己封装了一个insert方法如下:    //插入数据
    public function insert($data='', $options=array(), $replace=false){
    
        $token = C('TOKEN_NAME', null, '__hash__');
        if($_POST[$token] && !empty($data)) $data[$token] = $_POST[$token];
    
        if($this->create($data, self::MODEL_INSERT)){
            $insert = $this->add('', $options, $replace);
        }
        if($insert){
            $return = array('status'=>1, 'id'=>$insert, 'info'=>'success');
        }else{
            $return = array('status'=>-1, 'error'=>$this->error);
        }
        return $return;
    }
当我开启令牌配置,然后调用 M('table')->insert();时,不传参数,默认取POST数据,这样是没有问题的. 但是,如果我接收POST数据,组装成data数组,传进去时,忘了把令牌数据也放进去时,它就会报令牌错误.为此,我只有在从POST里取到令牌,追加到data数组中...
最佳答案
评论( 相关
后面还有条评论,点击查看>>