Yii中Model(模型)的创建及使用方法
《PHP实例:Yii中Model(模型)的创建及使用方法》要点: PHP学习本文实例分析了Yii中Model(模型)的创建及使用办法.分享给大家供大家参考,具体如下: YII 实现了两种模型,表单模型(CFormModel类)和Active Record模型(CAtiveRecord类),它们都继承自CModel类. CFormModel代表的数据模型是从HTML表单收集的输入,封装了所有逻辑(如表单的验证和其它业务逻辑,应用到表单的域上).它能将数据存储在内 存中,或者在一个Active Record的赞助下,存入数据库里. 数据库连接操作 在config/main.php中 'db'=>array( 'connectionString' => 'mysql:host=localhost;dbname=oss','emulatePrepare' => true,'username' => 'root','password' => 'hahaha','charset' => 'utf8',//表前缀 'tablePrefix'=>"oss_" ), 打开注释,php要支持pdo 查看操作日志 //显示日志信息,包括sql的查询信息 array( 'class'=>'CWebLogRoute',), 将注释打开 一. 基于CActiveRecord的Model Active Record(AR) 是一种设计模式,用面向对象的方式抽象的拜访数据,Yii中,每一个AR对象的实例都可以是CActiveRecord类或者它的子类.它包装了数据库表 或视图中的一行记录,并封装了所有的逻辑和风闻数据库的细节,有大部分的业务逻辑,必须使用这种模型.数据库表中一行每列字段的值对应AR对象的一个属 性.它将表映射到类,行映射到对象,列则映射到对象的数据.也就是说每一个Active Record类的实例代表了数据库中表的一行.但一个 Active Record类不单单是数据库表中的字段跟类中属性的映射关系.它还需要在这些数据上处理一些业务逻辑,定义了所有对数据库的读写操作. 1) 声明一个基于CActiveRecord 类的Model class Post extends CActiveRecord { public static function model($className=__CLASS__) { return parent::model($className); } public function tableName() { return '{{post}}'; } public function primaryKey() { return 'id'; // return array('pk1','pk2'); } } 2) 使用父类的办法完成数据库操作 (1) Insert: $post=new Post; $post->title='sample post'; $post->content='content for the sample post'; $post->create_time=time(); $post->save(); (2) Select: 常用几种办法 // find the first row satisfying the specified condition $post=Post::model()->find($condition,$params); // find the row with the specified primary key $post=Post::model()->findByPk($postID,$condition,$params); // find the row with the specified attribute values $post=Post::model()->findByAttributes($attributes,$params); // find the first row using the specified SQL statement $post=Post::model()->findBySql($sql,$params); $criteria=new CDbCriteria; $criteria->select='title'; // only select the 'title' column $criteria->condition='postID=:postID'; $criteria->params=array(':postID'=>10); $post=Post::model()->find($criteria); $post=Post::model()->find(array( 'select'=>'title','condition'=>'postID=:postID','params'=>array(':postID'=>10),)); // find all rows satisfying the specified condition $posts=Post::model()->findAll($condition,$params); // find all rows with the specified primary keys $posts=Post::model()->findAllByPk($postIDs,$params); // find all rows with the specified attribute values $posts=Post::model()->findAllByAttributes($attributes,$params); // find all rows using the specified SQL statement $posts=Post::model()->findAllBySql($sql,$params); // get the number of rows satisfying the specified condition $n=Post::model()->count($condition,$params); // get the number of rows using the specified SQL statement $n=Post::model()->countBySql($sql,$params); // check if there is at least a row satisfying the specified condition $exists=Post::model()->exists($condition,$params); (3) Update // update the rows matching the specified condition Post::model()->updateAll($attributes,$params); // update the rows matching the specified condition and primary key(s) Post::model()->updateByPk($pk,$attributes,$params); // update counter columns in the rows satisfying the specified conditions Post::model()->updateCounters($counters,$params); (4) Delete $post=Post::model()->findByPk(10); // assuming there is a post whose ID is 10 $post->delete(); // delete the rows matching the specified condition Post::model()->deleteAll($condition,$params); // delete the rows matching the specified condition and primary key(s) Post::model()->deleteByPk($pk,$params); (5) 使用事务 $model=Post::model(); $transaction=$model->dbConnection->beginTransaction(); try { // find and save are two steps which may be intervened by another request // we therefore use a transaction to ensure consistency and integrity $post=$model->findByPk(10); $post->title='new post title'; $post->save(); $transaction->commit(); } catch(Exception $e) { $transaction->rollBack(); } 二. 基于CFormModel 的Model 编写表单需要的HTML之前,我们需要决定我们希望用户输入哪些数据,以及应该符合什么规则.一个模型类可以用来记录这些信息,模型是保持用户输入并进行验证的核心 根据我们如何使用用户的输入,我们可以创建两种类型的模型.如果用户输入的数据被收集,使用,然后丢弃,我们将创建一个表单模型(form model); 如果用户输入的数据被保存到数据库中,我们则会使用 active record .这两种模型都继承了他们相同的基类CModel中定义的表单的通用接 口. 1) 模型类的定义 下面的例子中,我们创建了一个LoginForm模型,用来收集用户在登陆页面的输入.由于登陆信息仅仅用于用户验证,并不需要保存,因此我们用form model创建 class LoginForm extends CFormModel { public $username; public $password; public $rememberMe=false; } LoginForm一共声明了三个属性(attributes),$username、$password、$rememberMe 用来记录用户输入的用户名、暗码、以及是否记住登陆的选项.因为$rememberMe有了默认值false,所以显示表单时对应的选框是没有勾选的. 提示:我们使用名"attributes",而不是"properties",来把他们和正常的属性(properties)进行区分. 2) 声明验证规则 一旦把用户提交的数据填充到模型,在使用之前,我们要检查他们是否合法.这是通过对输入进行一组规则验证实现的.我们在rulers()办法中通过配置一个数组来定义验证规则 class LoginForm extends CFormModel { public $username; public $password; public $rememberMe=false; private $_identity; public function rules() { return array( array('username,password','required'),array('rememberMe','boolean'),array('password','authenticate'),); } public function authenticate($attribute,$params) { if(!$this->hasErrors()) // we only want to authenticate when no input errors { $this->_identity=new UserIdentity($this->username,$this->password); if(!$this->_identity->authenticate()) $this->addError('password','Incorrect password.'); } } } 上面的代码指明了用户名和暗码是必须得,暗码需要被验证,rememberMe必须是布尔型 rules()中返回的每条规则,必须依照如下格式 array('AttributeList','Validator','on'=>'ScenarioList',...附加选项(additional options)) AttributeList 是一个被逗号分隔的需要验证的属性名列表.Validator 指出了需要做怎样的验证.可选的on 参数指出了该规则应用的场景列表,(additional options)是对应的name-value,用于初始对应验证器的相关属性 在一个规则中指定Validator有三种方法,首先Validator可以使该类的一个方法,比如上面例子中的authenticate.该Validator方法必须依照如下的格式声明
代码如下:
public function ValidatorName($attribute,$params) { ... }
其次 Validator 可以使验证器的类名,当规则适用时,一个验证器类的实例会被创建并进行实际的验证.规则里的附加属性,用于初始实例的相关属性.验证器类必须继承于CValidator 提示:当对active record模型指定规则的时候,我们可以使用特殊的参数‘on', 该参数可以使'insert' 或者 'update',可以让规则分别在插入或者更新的时候适用.如果没有生命,该规则会在任何调用save()的时候适用. 第三、Validator 可以使验证器类预先定义的别名.在上面的例子中,“required”便是CRequiredValidator的别名,用来验证属性不能为空.下面是预定义的验证器类别名的列表 ? boolean:CBooleanValidator的别名,验证属性的值是否是CBooleanValidator::trueValue 或者 CBooleanValidator::falseValue 下面我们给出一些使用预定义验证器的例子. // username is required array('username',// username must be between 3 and 12 characters array('username','length','min'=>3,'max'=>12),// when in register scenario,password must match password2 array('password','compare','compareAttribute'=>'password2','on'=>'register'),// when in login scenario,password must be authenticated array('password','authenticate','on'=>'login'), 3) 平安属性的设置 当一个模型创建之后,我们往往需要根据用户的输入,为它填充属性.这可以方便的通过下面批量赋值的方式来实现 $model=new LoginForm; if(isset($_POST['LoginForm'])) $model->attributes=$_POST['LoginForm']; 最后那条语句便是批量赋值,把$_POST['LoginForm']中每个属性都赋值到对应的模型属性中,它等价于下面的语句 foreach($_POST['LoginForm'] as $name=>$value) { if($name is a safe attribute) $model->$name=$value; } 声明属性是否是平安属性是个至关重要的工作.例如,如果我把把数据表的主键暴露为平安属性,那么便可以通过修改主键的值,来管理本没有权限管理的数据,进行攻击. 4) 1.1版中的平安属性 在1.1版中,如果属性在适用的规则中指定了验证器,则认为是平安的.例如 array('username,'required','on'=>'login,register'),array('email', 上面的代码中用户名和暗码属性在login的场景下不允许为空.用户名、暗码邮箱在register的场景下不允许为空.因此如果在login的场景下 进 行批量赋值,仅仅用户名和暗码会被赋值,因为login场景下验证规则里仅出现了这两个属性,但是如果是在register场景下,那么这三个属性都 会被 赋值. // in login scenario $model=new User('login'); if(isset($_POST['User'])) $model->attributes=$_POST['User']; // in register scenario $model=new User('register'); if(isset($_POST['User'])) $model->attributes=$_POST['User']; 那么为什么我们使用如此的策略来决定一个属性是否是平安属性呢?因为一个属性,已经有了一个或者多个对个进行校验的规则,那么我还需要担心吗? 需要记住的是,验证器是用来检测用户输入的数据,而不是我们用代码产生的数据(例如 时间戳,自增的主键等).因此不要给那些不需要用户输入的属性添加验证器. 有时候我们想声明一些属性为平安属性,但是又不必给指定一个验证规则.例如文章的正文属性,我们可以允许用户的任何输入.为了实现这个目标,我们可以用safe规则.
代码如下:
array('content','safe')
对应的也有一个unsafe规则,来指定哪些属性是不平安的
代码如下:
array('permission','unsafe')
unsafe并不常用,对你以前定义的平安属性来说,这是个例外 5) 获取验证错误 当验证结束后,任何可能的错误都存储在模型的实例中.我们可以通过调用CModel::getErrors() 和 CModel::getError()重新获取到.这两个方法的区别在于,第一个可以返回指定模型属性的所有错误,而第二个方法只返回了第一条错误. 6) 属性标签 设计表单的时候,我们需要为用户的输入框显示一个标签,来提示用户输入.尽管我们可以再form中写死,但是如果我们在相应的模型中指定的话会更加方便和灵活 默认情况下,CModel 会简单的返回属性的名字作为标签.这可以通过重写attributeLabels() 办法来自定义.在接下来章节中我们将看到,在模型中指定标签可以让我们更快更强大的创建一个form表单 希望本文所述对大家基于yii框架的php程序设计有所赞助. 《PHP实例:Yii中Model(模型)的创建及使用方法》是否对您有启发,欢迎查看更多与《PHP实例:Yii中Model(模型)的创建及使用方法》相关教程,学精学透。编程之家 52php.cn为您提供精彩教程。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |