使用cmodel类可定义不与数据库关联的模型,如表单模型,通过继承cmodel并定义属性、rules()验证规则和自定义方法实现;2. 使用cactiverecord类可定义与数据库表关联的模型,需重写tablename()指定表名,并通过rules()、relations()、attributelabels()等方法定义验证、关联和标签;3. cactiverecord支持高级操作,如使用cdbcriteria构建复杂查询、事务处理、关联查询和作用域(scopes)来简化常用查询;4. 验证规则在rules()中定义,每个规则为数组,包含属性名、验证器及可选参数,支持required、email、length等内置验证器;5. 模型关系在relations()中定义,支持has_one、has_many、belongs_to、many_many和stat五种类型,通过with()方法进行关联查询可避免n+1性能问题。所有模型功能均通过继承cmodel或cactiverecord实现,并在控制器中实例化使用,完整支持数据验证、业务逻辑处理和数据库交互。

Yii 框架的模型是 MVC (Model-View-Controller) 架构中的一部分,负责处理数据和业务逻辑。它代表应用程序中的数据结构,并提供访问和操作这些数据的方法。在 Yii 中,模型通常对应于数据库表,但也可以代表其他数据源,例如文件或 API。Yii 通过
CModel类及其子类,如
CActiveRecord,来定义模型。
Yii 框架中定义模型的方式主要有两种:使用
CModel类或
CActiveRecord类。
使用 CModel 定义模型
如何定义一个不与数据库直接关联的模型?
CModel是 Yii 中所有模型类的基类。当你需要创建一个不直接与数据库表关联的模型时,例如处理表单数据或配置信息,你可以继承
CModel类。
例如,假设你需要创建一个处理用户登录表单的模型:
class LoginForm extends CModel
{
public $username;
public $password;
public $rememberMe = false;
private $_identity;
public function rules()
{
return array(
// username 和 password 必须填写
array('username, password', 'required'),
// rememberMe 是布尔值
array('rememberMe', 'boolean'),
// password 需要验证
array('password', 'authenticate'),
);
}
public function attributeLabels()
{
return array(
'username' => '用户名',
'password' => '密码',
'rememberMe' => '记住我',
);
}
public function authenticate($attribute, $params)
{
if (!$this->hasErrors()) {
$this->_identity = new UserIdentity($this->username, $this->password);
if (!$this->_identity->authenticate())
$this->addError('password', '用户名或密码不正确。');
}
}
public function login()
{
if ($this->_identity === null) {
$this->_identity = new UserIdentity($this->username, $this->password);
$this->_identity->authenticate();
}
if ($this->_identity->errorCode === UserIdentity::ERROR_NONE) {
return Yii::app()->user->login($this->_identity, $this->rememberMe ? 3600 * 24 * 30 : 0);
} else
return false;
}
}在这个例子中,
LoginForm模型定义了
username、
password和
rememberMe三个属性。
rules()方法定义了验证规则,
attributeLabels()方法定义了属性的标签,用于在表单中显示。
authenticate()方法用于验证用户名和密码,
login()方法用于登录用户。注意,这里没有直接操作数据库,而是使用了
UserIdentity类进行用户验证。
使用 CActiveRecord 定义模型
如何定义一个与数据库表关联的模型?
CActiveRecord是 Yii 中用于处理数据库表的模型类。它提供了方便的方法来执行 CRUD (Create, Read, Update, Delete) 操作。当你需要创建一个与数据库表关联的模型时,你应该继承
CActiveRecord类。
例如,假设你有一个名为
users的数据库表,包含
id、
username和
User模型来代表这个表:
class User extends CActiveRecord
{
/**
* @return string the associated database table name
*/
public function tableName()
{
return 'users';
}
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
return array(
array('username, email', 'required'),
array('username', 'length', 'max' => 50),
array('email', 'email'),
);
}
/**
* @return array relational rules.
*/
public function relations()
{
return array(
// 定义关系,例如一个用户可以有多个帖子
'posts' => array(self::HAS_MANY, 'Post', 'user_id'),
);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'ID',
'username' => '用户名',
'email' => '邮箱',
);
}
/**
* Returns the static model of the specified AR class.
* Please note that you should have this exact method in all your CActiveRecord descendants!
* @param string $className active record class name.
* @return User the static model class
*/
public static function model($className = __CLASS__)
{
return parent::model($className);
}
}在这个例子中,
tableName()方法返回数据库表的名称,
rules()方法定义了验证规则,
relations()方法定义了与其他模型的关系,
attributeLabels()方法定义了属性的标签。
model()方法是一个静态方法,用于返回模型的实例。
你可以使用以下代码来查询数据库中的用户:
$user = User::model()->findByPk(1); // 根据主键查找用户
echo $user->username; // 输出用户名
$users = User::model()->findAll(); // 查找所有用户
foreach ($users as $user) {
echo $user->email . '
'; // 输出所有用户的邮箱
}CActiveRecord 的高级用法
如何使用 CActiveRecord 进行更复杂的操作?
技术上面应用了三层结构,AJAX框架,URL重写等基础的开发。并用了动软的代码生成器及数据访问类,加进了一些自己用到的小功能,算是整理了一些自己的操作类。系统设计上面说不出用什么模式,大体设计是后台分两级分类,设置好一级之后,再设置二级并选择栏目类型,如内容,列表,上传文件,新窗口等。这样就可以生成无限多个二级分类,也就是网站栏目。对于扩展性来说,如果有新的需求可以直接加一个栏目类型并新加功能操作
除了基本的 CRUD 操作,
CActiveRecord还提供了许多高级功能,例如:
-
查询条件: 可以使用
CDbCriteria
类来构建复杂的查询条件。 -
事务: 可以使用
CDbTransaction
类来执行事务操作。 -
关联查询: 可以使用
relations()
方法定义模型之间的关系,并使用with()
方法进行关联查询。 -
作用域: 可以使用
scopes()
方法定义常用的查询条件,并在查询时使用。
例如,假设你需要查询所有用户名以 "test" 开头的用户,并按照注册时间排序:
$criteria = new CDbCriteria;
$criteria->addCondition('username LIKE :username');
$criteria->params = array(':username' => 'test%');
$criteria->order = 'create_time DESC';
$users = User::model()->findAll($criteria);或者,你可以使用作用域来简化查询:
class User extends CActiveRecord
{
public function scopes()
{
return array(
'testUsers' => array(
'condition' => 'username LIKE :username',
'params' => array(':username' => 'test%'),
'order' => 'create_time DESC',
),
);
}
}
$users = User::model()->testUsers()->findAll();Yii 模型中的验证规则
如何编写有效的模型验证规则?
Yii 的模型验证规则使用
rules()方法定义。每个规则都是一个数组,包含要验证的属性、验证器和可选的参数。Yii 提供了许多内置的验证器,例如
required、
length、
numerical等。你也可以自定义验证器。
以下是一些常用的验证规则示例:
array('username, password', 'required'):username
和password
属性必须填写。array('email', 'email'):email
属性必须是有效的电子邮件地址。array('username', 'length', 'max' => 50):username
属性的长度不能超过 50 个字符。array('age', 'numerical', 'integerOnly' => true):age
属性必须是整数。array('status', 'in', 'range' => array(1, 2, 3)):status
属性的值必须在 1、2 或 3 之间。
你可以使用以下代码来验证模型:
$model = new User;
$model->attributes = $_POST['User']; // 从 POST 数据中设置属性
if ($model->validate()) {
// 验证通过
$model->save(); // 保存到数据库
} else {
// 验证失败
print_r($model->getErrors()); // 输出错误信息
}模型关系(Relations)在Yii框架中的作用
如何在模型中定义和使用关系?
Yii 的模型关系允许你在不同的模型之间建立关联。例如,一个用户可以有多个帖子,一个帖子属于一个用户。Yii 提供了三种类型的关系:
- HAS_ONE: 一个模型对应另一个模型的一个实例。
- HAS_MANY: 一个模型对应另一个模型的多个实例。
- BELONGS_TO: 一个模型属于另一个模型的一个实例。
- MANY_MANY: 一个模型与另一个模型的多个实例相关联,通过一个连接表。
- STAT: 一个模型与另一个模型的关系基于聚合查询的结果。
你可以在
relations()方法中定义模型关系。例如,假设你有一个
User模型和一个
Post模型,一个用户可以有多个帖子:
class User extends CActiveRecord
{
public function relations()
{
return array(
'posts' => array(self::HAS_MANY, 'Post', 'user_id'),
);
}
}
class Post extends CActiveRecord
{
public function relations()
{
return array(
'user' => array(self::BELONGS_TO, 'User', 'user_id'),
);
}
}你可以使用以下代码来访问模型关系:
$user = User::model()->findByPk(1);
echo $user->username; // 输出用户名
foreach ($user->posts as $post) {
echo $post->title . '
'; // 输出用户的所有帖子标题
}
$post = Post::model()->findByPk(1);
echo $post->user->username; // 输出帖子所属用户的用户名使用
with()方法进行关联查询可以提高性能,避免 N+1 查询问题。例如:
$users = User::model()->with('posts')->findAll();
foreach ($users as $user) {
echo $user->username . '
';
foreach ($user->posts as $post) {
echo '- ' . $post->title . '
';
}
}这样,Yii 将会使用一条 SQL 语句查询所有用户及其帖子,而不是为每个用户执行一次查询。









