转 Yii2模型简介
模型Model是MVC模型中的M,是业务数据、业务规则和业务逻辑的对象。Yii很好的展现了这点,用户可用创建自己定义的模型,比如给一个的表单定义一个模型,这样就把表单处...
模型Model是MVC模型中的M,是业务数据、业务规则和业务逻辑的对象。
Yii很好的展现了这点,用户可用创建自己定义的模型,比如给一个的表单定义一个模型,这样就把表单处理作为一个业务逻辑转化成了模型。
可通过继承 yii\base\Model 或它的子类定义模型类,yii\base\Model又继承yii\base\Component(基本组件),组件又继承自yii\base\BaseObject(基本对象),基本对象实例了yii\base\Configurable这个空接口。 基类yii\base\Model支持许多实用的特性:...
|-转 Yii2模型简介-属性
属性 ¶模型通过 属性 来代表业务数据,每个属性像是模型的公有可访问属性, yii\base\Model::attributes() 指定模型所拥有的属性。可像访问一个对象属性一样访问模型的属性:$...
属性 ¶
模型通过 属性 来代表业务数据,每个属性像是模型的公有可访问属性, yii\base\Model::attributes() 指定模型所拥有的属性。
可像访问一个对象属性一样访问模型的属性:
$model = new \app\models\ContactForm;
// "name" 是ContactForm模型的属性
$model->name = 'example';
echo $model->name;
也可像访问数组单元项一样访问属性,这要感谢yii\base\Model支持 ArrayAccess 数组访问 和 ArrayIterator 数组迭代器:
$model = new \app\models\ContactForm;
// 像访问数组单元项一样访问属性
$model['name'] = 'example';
echo $model['name'];
// 迭代器遍历模型
foreach ($model as $name => $value) {
echo "$name: $value\n";
}
定义属性
默认情况下你的模型类直接从yii\base\Model继承,所有 non-static public非静态公有 成员变量都是属性。 例如,下述ContactForm
模型类有四个属性name
, email
, subject
and body
, ContactForm
模型用来代表从HTML表单获取的输入数据。
namespace app\models;
use yii\base\Model;
class ContactForm extends Model
{
public $name;
public $email;
public $subject;
public $body;
}
另一种方式是可覆盖 yii\base\Model::attributes() 来定义属性,该方法返回模型的属性名。 例如 yii\db\ActiveRecord 返回对应数据表列名作为它的属性名, 注意可能需要覆盖魔术方法如__get()
, __set()
使属性像普通对象属性被访问。
属性标签
当属性显示或获取输入时,经常要显示属性相关标签, 例如假定一个属性名为firstName
, 在某些地方如表单输入或错误信息处,你可能想显示对终端用户来说更友好的 First Name
标签。...
|-转 Yii2模型简介-场景
场景模型可能在多个 场景 下使用,例如 User 模块可能会在收集用户登录输入, 也可能会在用户注册时使用。在不同的场景下, 模型可能会使用不同的业务规则和逻辑, 例如 em...
场景
模型可能在多个 场景 下使用,例如 User
模块可能会在收集用户登录输入, 也可能会在用户注册时使用。在不同的场景下, 模型可能会使用不同的业务规则和逻辑, 例如 email
属性在注册时强制要求有,但在登陆时不需要。
模型使用 yii\base\Model::scenario 属性保持使用场景的跟踪, 默认情况下,模型支持一个名为 default
的场景, 如下展示两种设置场景的方法:
// 场景作为属性来设置
$model = new User;
$model->scenario = 'login';
// 场景通过构造初始化配置来设置
$model = new User(['scenario' => 'login']);
默认情况下,模型支持的场景由模型中申明的 验证规则 来决定, 但你可以通过覆盖yii\base\Model::scenarios()方法来自定义行为, 如下所示:
namespace app\models;
use yii\db\ActiveRecord;
class User extends ActiveRecord
{
const SCENARIO_LOGIN = 'login';
const SCENARIO_REGISTER = 'register';
public function scenarios()
{
return [
self::SCENARIO_LOGIN => ['username', 'password'],
self::SCENARIO_REGISTER => ['username', 'email', 'password'],
];
}
}
信息:在上述和下述的例子中,模型类都是继承yii\db\ActiveRecord, 因为多场景的使用通常发生在Active Record 类中.
scenarios()
方法返回一个数组,数组的键为场景名,值为对应的 active attributes活动属性。 活动属性可被 块赋值 并遵循验证规则 在上述例子中,username
和 password
在login
场景中启用,在 register
场景中, 除了 username
and password
外 email
也被启用。...
|-转 Yii2模型简介-验证规则
验证规则当模型接收到终端用户输入的数据, 数据应当满足某种规则(称为 验证规则, 也称为 业务规则)。 例如假定ContactForm模型,你可能想确保所有属性不为空且 email 属性...
验证规则
当模型接收到终端用户输入的数据, 数据应当满足某种规则(称为 验证规则, 也称为 业务规则)。 例如假定ContactForm
模型,你可能想确保所有属性不为空且 email
属性包含一个有效的邮箱地址, 如果某个属性的值不满足对应的业务规则, 相应的错误信息应显示,以帮助用户修正错误。
可调用 yii\base\Model::validate() 来验证接收到的数据, 该方法使用yii\base\Model::rules()申明的验证规则来验证每个相关属性, 如果没有找到错误,会返回 true, 否则它会将错误保存在 yii\base\Model::errors 属性中并返回false,例如:
$model = new \app\models\ContactForm;
// 用户输入数据赋值到模型属性
$model->attributes = \Yii::$app->request->post('ContactForm');
if ($model->validate()) {
// 所有输入数据都有效 all inputs are valid
} else {
// 验证失败:$errors 是一个包含错误信息的数组
$errors = $model->errors;
}
通过覆盖 yii\base\Model::rules() 方法指定模型 属性应该满足的规则来申明模型相关验证规则。 下述例子显示ContactForm
模型申明的验证规则:
public function rules()
{
return [
// name, email, subject 和 body 属性必须有值
[['name', 'email', 'subject', 'body'], 'required'],
// email 属性必须是一个有效的电子邮箱地址
['email', 'email'],
];
}
一条规则可用来验证一个或多个属性,一个属性可对应一条或多条规则。 更多关于如何申明验证规则的详情请参考 验证输入 一节....
|-转 Yii2模型简介-块赋值
块赋值块赋值只用一行代码将用户所有输入填充到一个模型,非常方便, 它直接将输入数据对应填充到 yii\base\Model::attributes() 属性。 以下两段代码效果是相同的, 都是将终...
块赋值
块赋值只用一行代码将用户所有输入填充到一个模型,非常方便, 它直接将输入数据对应填充到 yii\base\Model::attributes() 属性。 以下两段代码效果是相同的, 都是将终端用户输入的表单数据赋值到 ContactForm
模型的属性, 明显地前一段块赋值的代码比后一段代码简洁且不易出错。
$model = new \app\models\ContactForm;
$model->attributes = \Yii::$app->request->post('ContactForm');//只需两行
$model = new \app\models\ContactForm;
$data = \Yii::$app->request->post('ContactForm', []);
$model->name = isset($data['name']) ? $data['name'] : null;
$model->email = isset($data['email']) ? $data['email'] : null;
$model->subject = isset($data['subject']) ? $data['subject'] : null;
$model->body = isset($data['body']) ? $data['body'] : null; //多了几行
安全属性
块赋值只应用在模型当前yii\base\Model::scenario 场景yii\base\Model::scenarios()方法 列出的称之为 安全属性 的属性上,例如,如果User
模型申明以下场景, 当当前场景为login
时候,只有username
and password
可被块赋值, 其他属性不会被赋值。...
|-转 Yii2模型简介-非安全属性
非安全属性如上所述,yii\base\Model::scenarios() 方法提供两个用处:定义哪些属性应被验证,定义哪些属性安全。 在某些情况下,你可能想验证一个属性但不想让他是安全的,...
非安全属性
如上所述,yii\base\Model::scenarios() 方法提供两个用处:定义哪些属性应被验证,定义哪些属性安全。 在某些情况下,你可能想验证一个属性但不想让他是安全的, 可在scenarios()
方法中属性名加一个惊叹号 !
。 例如像如下的secret
属性。
public function scenarios()
{
return [
'login' => ['username', 'password', '!secret'],
];
}
当模型在 login
场景下,三个属性都会被验证, 但只有 username
和 password
属性会被块赋值, 要对secret
属性赋值,必须像如下例子明确对它赋值。...
|-转 Yii2模型简介-数据导出
数据导出模型通常要导出成不同格式,例如,你可能想将模型的一个集合转成JSON或Excel格式, 导出过程可分解为两个步骤:模型转换成数组;数组转换成所需要的格式。你只需...
数据导出
模型通常要导出成不同格式,例如,你可能想将模型的一个集合转成JSON或Excel格式, 导出过程可分解为两个步骤:
- 模型转换成数组;
- 数组转换成所需要的格式。
你只需要关注第一步,因为第二步可被通用的 数据转换器如yii\web\JsonResponseFormatter来完成。
将模型转换为数组最简单的方式是使用 yii\base\Model::attributes() 属性, 例如:
$post = \app\models\Post::findOne(100);
$array = $post->attributes;
yii\base\Model::attributes() 属性会返回 所有 yii\base\Model::attributes() 申明的属性的值。...
|-转 Yii2模型简介-字段
字段字段是模型通过调用yii\base\Model::toArray() 生成的数组的单元名。默认情况下,字段名和属性名对应,但是你可以通过覆盖 fields() 和/或 yii\base\Model::extraFields() ...
字段
字段是模型通过调用yii\base\Model::toArray() 生成的数组的单元名。
默认情况下,字段名和属性名对应,但是你可以通过覆盖 fields() 和/或 yii\base\Model::extraFields() 方法来改变这种行为, 两个方法都返回一个字段定义列表,fields()
方法定义的字段是默认字段, 表示toArray()
方法默认会返回这些字段。 extraFields()
方法定义额外可用字段, 通过toArray()
方法指定$expand
参数来返回这些额外可用字段。 例如如下代码会返回fields()
方法定义的所有字段和extraFields()
方法定义的prettyName
and fullAddress
字段。
$array = $model->toArray([], ['prettyName', 'fullAddress']);
可通过覆盖 fields()
来增加、删除、重命名和重定义字段, fields()
方法返回值应为数组, 数组的键为字段名,数组的值为对应的可为属性名或匿名函数返回的字段定义对应的值。 特使情况下,如果字段名和属性定义名相同,可以省略数组键, 例如:
// 明确列出每个字段,特别用于你想确保数据表或模型
// 属性改变不会导致你的字段改变(保证后端的API兼容)。
public function fields()
{
return [
// 字段名和属性名相同
'id',
// 字段名为 "email",对应属性名为 "email_address"
'email' => 'email_address',
// 字段名为 "name", 值通过PHP代码返回
'name' => function () {
return $this->first_name . ' ' . $this->last_name;
},
];
}
// 过滤掉一些字段,特别用于
// 你想继承父类实现并不想用一些敏感字段
public function fields()
{
$fields = parent::fields();
// 去掉一些包含敏感信息的字段
unset($fields['auth_key'], $fields['password_hash'], $fields['password_reset_token']);
return $fields;
}
警告:由于模型的所有属性会被包含在导出数组,最好检查数据确保没包含敏感数据, 如果有敏感数据,应覆盖 fields()
方法过滤掉, 在上述列子中,我们选择过滤掉 auth_key
, password_hash
and password_reset_token
。...
|-转 Yii2模型简介-最佳实践
最佳实践模型是代表业务数据、规则和逻辑的中心地方,通常在很多地方重用, 在一个设计良好的应用中,模型通常比 控制器代码多。归纳起来,模型可包含属性来展示业务数据;...
最佳实践
模型是代表业务数据、规则和逻辑的中心地方,通常在很多地方重用, 在一个设计良好的应用中,模型通常比 控制器代码多。
归纳起来,模型
- 可包含属性来展示业务数据;
- 可包含验证规则确保数据有效和完整;
- 可包含方法实现业务逻辑;
- 不应直接访问请求,session和其他环境数据, 这些数据应该由控制器传入到模型;
- 应避免嵌入HTML或其他展示代码,这些代码最好在 视图中处理;
- 单个模型中避免太多的 场景.
在开发大型复杂系统时应经常考虑最后一条建议, 在这些系统中,模型会很大并在很多地方使用,因此会包含需要规则集和业务逻辑, 最后维护这些模型代码成为一个噩梦, 因为一个简单修改会影响好多地方, 为确保模型好维护,最好使用以下策略:...