文档章节

Yii学习笔记:实现类似于ThinkPHP的模型字段映射,字段别名

吾爱
 吾爱
发布于 2013/12/29 16:53
字数 870
阅读 1198
收藏 2

在TP中,我们只要在模型类中定义一个


protected $_map = array(
        'name' =>'username', // 把表单中name映射到数据表的username字段
        'mail'  =>'email', // 把表单中的mail映射到数据表的email字段
    );



这样,我们前端模板中使用 <input type=text name="name"/>


在模型收集表单数据时会自动将值同时映射到username字段上。

好处是避免数据库字段直接暴露。

但很遗憾,我在学习Yii过程中没有找到类似的机制,而Yii的类库很多,我又不敢贸然自己扩展,总觉得在某个角落里有某个类可能已经提供了解决方案,怕自己做重复无意义之举。

经过一系列的思想斗争,楼主还是决定自己动手啦。。

方法很简单,请先看代码:


<?php
class CustomModel extends CActiveRecord {
    //定义所需要收集的属性
    public $username;
    public $email;
    public $passwd;
    public $password;
    public $password1;
    
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }
 
    public function tableName()
    {
        return '{{custom}}';
    }
    
    public function rules(){
        return array(
            array("username,password,email,password1","safe")
        );
    }
    //字段映射配置
    protected $_alias_ = array(
        "passwd" => "password"
    );
    //通过引用传递处理映射
    protected function afterConstruct(){
        parent::afterConstruct();
        //字段映射处理
        if(!empty($this->_alias_)){
            foreach($this->_alias_ as $a => $b){
                if(property_exists($this,$a) && property_exists($this,$b)){
                    $this->$a = &$this->$b;
                }
            }
        }
    }
}



模板:



<?php defined("APP_NAME") or exit;?>
<form action="" method="post">
    <table>
        <tr>
            <th>用户名:</th>
            <td><input type="text" name="username" placeholder="请设置您的账号名" value=""/></td>
        </tr>
        <tr>
            <th>邮箱:</th>
            <td><input type="email" name="email" placeholder="example@website" value=""/></td>
        </tr>
        <tr>
            <th>密码:</th>
            <td><input type="password" name="password" value=""/></td>
        </tr>
        <tr>
            <th>重复密码:</th>
            <td><input type="password" name="password1" value=""/></td>
        </tr>
        <tr>
            <td colspan="2"><input type="submit" value="提交"/></td>
        </tr>
    </table>
</form>



可以发现,我在表单中使用了password字段名作为密码,但是我数据库中的字段是passwd,如果直接这样收集表单,是无法将密码数据入库的。


所以我在模型类中定义了1个方法:

afterConstruct()
一个属性
protected $_alias_
我们在$_alias_这个属性里面定义映射,比如我定义了 "passwd"=>"password"的映射。

afterConstruct()这个方法是在你实例化模型类之后执行的,可以看成在 $model = new CustomModel()的时候触发,这里面主要做了一个工作,就是检测$_alias_有没有定义映射,如果有的话,我们使用php的引用传递特性来使两个字段指向同一个值。

最后,为了可以全局使用,建议在components/目录下建立一个 CommonModel类,将afterConstruct()方法放在这个类里,其他模型继承这个类就可以了,这样只要在各自的模型中定义_alias_属性即可。

/////////基于事件的处理方法

<?php
class CommonAR extends CActiveRecord{
    function init(){
        $this->onAfterConstruct = array($this,"autoMap");
    }
    //字段映射配置
    protected $_alias_ = array(
    );
    
    function autoMap($event){
        //字段映射处理
        if(!empty($this->_alias_)){
            foreach($this->_alias_ as $a => $b){
                if(property_exists($this,$a) && property_exists($this,$b)){
                    $this->$a = &$this->$b;
                }
            }
        }
    }
}



假设在components/下创建一个 CommonAR类,我们在init()方法中注册一个事件
$this->onAfterConstruct = array($this,"autoMap");
对应的事件方法就是类里面的autoMap()

然后创建具体模型的时候继承CommonAR类,定义$_alias_即可。



© 著作权归作者所有

共有 人打赏支持
吾爱
粉丝 142
博文 267
码字总数 90553
作品 0
后端工程师
私信 提问
加载中

评论(2)

吾爱
吾爱

引用来自“别人说我名字很长”的评论

老爱不错哦,等会哥哥也写一个

更新了,增加了一个基于事件的处理办法,代码更干净了。
别人说我名字很长
别人说我名字很长
老爱不错哦,等会哥哥也写一个
Yii 字段映射 如何实现?

Yii有没有ThinkPHP里面的字段映射功能?怎么实现?初学Yii,目前只知道主键可以。 ThinkPHP的字段映射功能可以让你在表单中隐藏真正的数据表字段,而不用担心放弃自动创建表单对象的功能,假...

Lucups
2013/03/21
965
3
ThinkPHP中的三大自动简介

ThinkPHP中的三大自动简介 文章TAG:thinkphp 自动简介 过期已备案域名,注册就能用!终身VIP会员,畅享源码下载织梦精美仿站,火热预定中! 本文较为详细的讲述了ThinkPHP中的三大自动,是非...

thinkyoung
2015/10/10
0
0
PHP框架 ThinkPHP3.2.3 Yii2 Laravel4.2 并发测试

一直听说PHP框架中Yii是多么多么的企业级,Laravel是多么多么的艺术、优雅、先进。而且他俩的性能又是多么多么的卓越,搞得我心痒痒的,好像去深入学习下。 由于我最近的新项目在用ThinkPHP开...

金三胖
2015/01/27
0
27
ThinkPHP 查询数据 select(findAll) 方法

ThinkPHP 查询数据 ThinkPHP 查询数据主要提供以下几类查询: select:普通查询,同 findAll() 方法 find:取得符合查询条件的一条记录 getBy动态查询:根据某个字段取得符合查询条件的一条记...

WangEven
2012/05/10
0
0
Phalconphp中文文档

一般都是直接看英文资料,大都能看得懂。但看到Phalcon框架如此优秀,在学习后就想和大家分享,但发现国内的人几乎没有使用的,故想翻译一下,一旦翻译才发现读懂和译出一篇好文章真的不太一...

netstu_
2012/11/21
11.3K
11

没有更多内容

加载失败,请刷新页面

加载更多

Angularjs实现控制器之间通信方式示例

利用angularjs开发项目中,控制器之间的通信,比如参数的传递,数据的传递,都是比较常见的。控制器之间的通信,显得尤为重要。常见的方式有如下两种:一、angular服务的方式;二、基于事件广...

前端攻城老湿
13分钟前
0
0
xshell使用xftp传输文件

12月11日任务 15.4 xshell使用xftp传输文件 15.5 使用pure-ftpd搭建ftp服务 1.xshell使用xftp传输文件 示例一:xshell使用sftp传输文件 新建一个会话 定义为sftp 连接登入 可以get文件,下载...

hhpuppy
15分钟前
1
0
深入解析Vuex实战总结

这篇文章主要介绍了Vuex的初探与实战小结,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下。如有不足之处,欢迎批评指正。 1.背景 最近在做一个单页面的管理后台项...

前端攻城小牛
16分钟前
1
0
eslint rules 规则

'rules': { "comma-dangle": ["error", "never"], //是否允许对象中出现结尾逗号 "no-cond-assign": 2, //条件语句的条件中不允许出现赋值运算符 "no-console": 2, //不允许出现console语句 ...

agenyun
59分钟前
2
0
类型判断时instanceof和equals的不同用法

接口设计时为了避免序列化的麻烦,将接口定义为参数为map<String,String>类型的接口,但是现在调用时需要转换当前的实体Bean为Map,接口接收方再把Map转换为另一个Bean实体。过程中的需要对类...

wangtx
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部