PHP的Yii框架的基本使用示例 |
本文标签:PHP,Yii 在 Yii 自动生成的代码里,我们总能在 admin 的界面看到 CGridView 的身影 。这是一个很好用的展示数据的表格控件,用的好可以明显地加快开发进度 。下面就让我们来探索一下 CGridView 的基本使用吧: 简单起见,我们的代码就用 Yii demo 中的 blog 例子来做修改 。首先,这是修改后的部分 Mysql 语句: drop table if exists `tbl_user`; CREATE TABLE tbl_user ( `user_id` INTEGER NOT NULL AUTO_INCREMENT comment 主键, `username` VARCHAR(128) NOT NULL comment 用户名, `nickname` VARCHAR(128) NOT NULL comment 昵称, `password` VARCHAR(128) NOT NULL comment 密码, `email` VARCHAR(128) NOT NULL comment 邮箱, `is_delete` tinyint not null default 0 comment 删除标志, unique key(`username`), primary key (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 comment=用户表; drop table if exists `tbl_post`; CREATE TABLE tbl_post ( `post_id` INTEGER NOT NULL AUTO_INCREMENT comment 主键, `title` VARCHAR(128) NOT NULL comment 标题, `content` TEXT NOT NULL comment 文章内容, `tags` TEXT comment 标签, `status` INTEGER NOT NULL comment 状态,0 = 草稿,1 = 审核通过,-1 = 审核不通过,2 = 发布, `create_time` INTEGER comment 创建时间, `update_time` INTEGER comment 更新时间, `author_id` INTEGER NOT NULL comment 作者, `is_delete` tinyint not null default 0 comment 删除标志, CONSTRAINT `post_ibfk_1` FOREIGN KEY (author_id) REFERENCES tbl_user (`user_id`) ON DELETE CASCADE ON UPDATE RESTRICT, primary key (`post_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 comment=日志表; 两个表一个存储作者信息一个存储日志,其中日志有一个外键关联到 user 。两个表里面的 is_delete 字段是标志该条记录是否被删除,0 为未删除,1 为已删除 。让我们看一下用 gii 生成的 Post 类的 relation 方法: /** * @return array relational rules. */ public function relations() { // NOTE: you may need to adjust the relation name and the related // class name for the relations automatically generated below. return array( comments => array(self::HAS_MANY, Comment, post_id), author => array(self::BELONGS_TO, User, author_id), ); } 其中的 author 外键作为 BELONGS_TO 关系存在,符合我们的预期 。 <?php $this->widget(zii.widgets.grid.CGridView, array( id=>post-grid, dataProvider=>$model->search(), filter=>$model, columns=>array( post_id, title, content, tags, status, create_time, update_time, author_id, is_delete, array( class=>CButtonColumn, ), ), )); ?> 看!虽然我们什么都没写,但这就是这个控件的最基础使用了 。dataProvider 是由 model 里面的 search 函数提供的数据,filter...暂时看不出这里的作用,columns 控制展示的每一列,其中最后一项的 CButtonColumn 向我们展示了三个按钮,分别是 查看 更新 和 删除 。 用 CGridView 展示我们真正要的数据形式: <?php $this->widget(zii.widgets.grid.CGridView, array( id=>post-grid, dataProvider=>$model->search(), filter=>$model, columns=>array( post_id, title, content, tags, status, create_time, update_time, author_id, is_delete, array( name=>is_delete, value=>is_delete?"是":"否" //value 是可以执行 php 语句的哦 ) array( class=>CButtonColumn, ), ), )); ?> 除此之外,还有一些常用的选项,都可以在 array 里面填写,下面是比较常见的使用方式(其他部分代码省略): array( name=>is_delete, value=>is_delete?"是":"否" //value 是可以执行 php 语句的哦 filter => array(0=>否,1=>是), //自己定义搜索过滤的方式,这里为 是 和 否 的下拉菜单 htmlOptions=>array(class=>delete), //可以定义 html 选项,这里是定义了带一个 delete 的类 ), 上面我们用 name 的话那是 model 里原来就有的字段,如果我们想展示自己定义的新内容呢,用 header : array( header=>备注, value=> display your data ), 添加 CCheckBoxColumn : <?php $this->widget(zii.widgets.grid.CGridView, array( id=>post-grid, dataProvider=>$model->search(), filter=>$model, columns=>array( array( selectableRows => 2, //允许多选,改为 0 时代表不允许修改,1 的话为单选 class => CCheckBoxColumn,//复选框 headerHtmlOptions => array(width=>18px),//头部的 html 选项 checkBoxHtmlOptions => array(name => myname,class=>myclass), //复选框的 html 选项 ), post_id, title, content, tags, status, create_time, update_time, author_id, is_delete, array( name=>is_delete, value=>is_delete?"是":"否", //value 是可以执行 php 语句的哦 filter => array(0=>否,1=>是), //自己定义搜索过滤的方式,这里为 是 和 否 的下拉菜单 htmlOptions=>array(class=>delete), //可以定义 html 选项,这里是定义了带一个 delete 的类 ), array( class=>CButtonColumn, ), ), )); 修改ButtonColumn: array( class=>ButtonColumn, template=>"{view} {update}", ), 也可以自定义按钮: array( class=>ButtonColumn, template=>"{view} {update} {print}", buttons=>array( print=>array( label=>打印, url=>Yii::app()->controller->createUrl("print", array("id"=>$data->post_id)), options=>array("target"=>"_blank"), ), ), ), 刷新时触发 Javascript: $js = <<<_JS_ function(){ alert(The ajax finish); } _JS_; $this->widget(zii.widgets.grid.CGridView, array( id=>post-grid, dataProvider=>$model->search(), filter=>$model, afterAjaxUpdate=>$js, //看这里,ajax 之后调用的 javascript 在这里.... columns=>array( array( selectableRows => 2, //允许多选,改为 0 时代表不允许修改,1 的话为单选 class => CCheckBoxColumn,//复选框 headerHtmlOptions => array(width=>18px), checkBoxHtmlOptions => array(name => myname,class=>myclass), ), .... 添加 关联表 相关字段的搜索: /** * @return array relational rules. */ public function relations() { // NOTE: you may need to adjust the relation name and the related // class name for the relations automatically generated below. return array( comments => array(self::HAS_MANY, Comment, post_id), author => array(self::BELONGS_TO, User, author_id), ); } 可以看到 POST 和 USER 表可以通过 author 键进行访问,例如: $model->author->nickname,而且 这里是 BELONGS_TO 关系 。 产品经理推了推眼镜:”我们要在日志的后台管理界面加一个功能,可以通过作者名称搜索到相应的文章 。这个比较急,今晚就要完成 。“ 淡定淡定,不就是改需求吗 。忽略进度要求,我们研究一下究竟要做什么 。 首先,我们进入 POST 的 model,在一开始的地方添加一个属性: class Post extends CActiveRecord { public $name; //添加一个 public 属性,代表作者名 然后改一下 Model 里面 search 的代码,改动部分都已经加了注释: public function search() { // @todo Please modify the following code to remove attributes that should not be searched. $criteria=new CDbCriteria; $criteria->with = array(author); //添加了和 author 的渴求式加载 $criteria->compare(post_id,$this->post_id); $criteria->compare(title,$this->title,true); $criteria->compare(content,$this->content,true); $criteria->compare(tags,$this->tags,true); $criteria->compare(status,$this->status); $criteria->compare(create_time,$this->create_time); $criteria->compare(update_time,$this->update_time); $criteria->compare(author_id,$this->author_id); //这里添加了一个 compare, username 是 User 表的字段,$this->name 是我们添加的属性,true 为模糊搜索 $criteria->compare(username,$this->name,true); return new CActiveDataProvider($this, array( criteria=>$criteria, )); }
<?php $this->widget(zii.widgets.grid.CGridView, array( id=>post-grid, dataProvider=>$model->search(), filter=>$model, columns=>array( post_id, title, content, tags, status, create_time, update_time, author_id, /*下面就是添加的代码啊*/ array( name=>作者名称, value=>$data->author->username, //定义展示的 value 值 filter=>CHtml::activeTextField($model,name), //添加搜索 filter ), array( class=>CButtonColumn, ), ), )); ?> 你是不是发现现在有了搜索框但是不起作用呢?哈哈,所以我们说文章要坚持看到最后 。我们要做的最后一步,就是在 rule 里面,把 name 属性加入到安全搜索字段中,要不然会被 Yii 认为是不安全字段而过滤掉的 。看,就在下面函数的最后一行,safe 前面多了个 name .... public function rules() { // NOTE: you should only define rules for those attributes that // will receive user inputs. return array( array(title, content, status, author_id, required), array(status, create_time, update_time, author_id, numerical, integerOnly=>true), array(title, length, max=>128), array(tags, safe), // The following rule is used by search(). // @todo Please remove those attributes that should not be searched. array(post_id, title, content, tags, status, create_time, update_time, author_id, name, safe, on=>search), ); }
|