Yii2—模型(Model)
模型(Model)
本部分将包含如下这方面的内容
1、模型的定义
一般在定义模型的时候都继承自yiiaseModel 或者yiidbActiveRecord。
1、属性的定义
一般情况下,在模型里面定义的属性是公共的并且是非静态的。在下面的示例中,LoginForm模型类声明了两个属性:用户名和密码。
2、属性的访问
模型的属性可以像访问对象的成员变量一样来访问。例如,一篇文章模型可能包含一个标题属性和内容属性,可以如下:
如果要一次获取模型的所有的属性,可用通过 attributes 属性来得到,下面的例子将得到post模型里面所有的属性,并以name-value的数组形式返回
4、属性标签
一般情况下在模型里面定义的属性都需要在前台界面显示出来,这个时候有一个对应的友好的文字提示就好了。属性标签就是用来干这个的。
在模型里面定义属性标签很简单,只需要重写yiiaseModel::attributeLabels() 方法即可,它返回的是name-value数组,名称为属性的名称,对应的值即为属性的标签名称。
如果某个属性没有定义对应的标签,Yii会使用yiiaseModel::generateAttributeLabel()方法自动生成对应的标签,
例如username 会生成 Username, orderNumber 生成 Order Number
3、场景
场景说的通俗点,就是不同条件下环境。举个用户注册的例子,普通用户在注册的时候只要用户名、密码、电子邮箱就可以了,而企业用户除了这些外还需要提供企业名称、法人名称、营业执照号什么的,这就是两个不同的场景。
为了让一个模型能使用在不同的场景下面,Yii里面提供了scenarios()方法,返回的也是name-value数组,name为每个不同 的场景,value是一个数组,为对应场景的所用到的属性。
如果没有在模型中定义场景scenarios(),那么将会使用默认的场景,即所有的属性都将使用。
如果在定义场景的同时还要保持默认的场景可用,那么就得需要调用父类的scenarios()
如果要给模型指定所使用的场景可以用下面的的几个方法
一般来说在表单模型中基本不需要指定场景,因为一个模型对应着一个表单,而默认的场景是返回这个模型里面所有的属性的,而且在对属性的批量赋值方面都是安全的。
4、验证
在通过模型的属性收集用户输入的数据的时候,通常情况下需要验证这些属性的值,例如不能不空、只能是字母等等。如果验证结果有错误就得需要在界面显示出这些错误信息来让用户修改。如
要定义模型的验证规则的只需要重写rules()。每个验证规则可以作用在多个属性上面,还可以指定这个验证规则所作用的场景。验证器可以用yiivalidatorsValidator的实例来指定
如果内置的验证器不满足你的需要,你可以在模型类里面通过方法的定义来实现自己的验证器。这个方法将被包装成 InlineValidator对象,并在其它验证规则之前先被调用
你只需要实现对属性的验证逻辑规则,并在验证失败的时候在模型里面添加相应的错误信息。
自定义验证器方法如下
public function myValidator($attribute, $params),其中名称可以随便命名。
下面这个验证器用来验证用户的年龄。
可以在满员某些条件的情况下才验证属性,例如一个属性的验证需要另外一个属性值(确认密码等),这个时候可以用when关键字来定义
在Yii2.0中不像Yii1.x,Yii2.0中的的验证规则和批量赋值是分开的,验证规则在模型中的rules()方法中实现,而批量赋值的安全(safe)属性在scenarios()中实现
如果没有定义场景scenarios()的话,
本部分将包含如下这方面的内容
- 模型的定义
- 属性
- 属性的定义
- 属性的访问
- 属性的批量读取和赋值
- 属性标签
- 场景
- 验证
- 验证规则的实现
- 自定义验证器和内置验证器
- 条件验证
- 验证规则和批量赋值
- 属性声明:可以在模型里面定义自己需要的属性。
- 属性标签:每个属性都有一个对应的标签以便在界面上显示友好的名称
- 批量属性赋值:可以一次为模型的多个属性赋值。
- 基于场景的数据验证功能。
1、模型的定义
一般在定义模型的时候都继承自yiiaseModel 或者yiidbActiveRecord。
- class Post extends yiiaseModel
- {
- .....
- }
1、属性的定义
一般情况下,在模型里面定义的属性是公共的并且是非静态的。在下面的示例中,LoginForm模型类声明了两个属性:用户名和密码。
- // LoginForm has two attributes: username and password
- class LoginForm extends yiiaseModel
- {
- public $username;
- public $password;
- }
2、属性的访问
模型的属性可以像访问对象的成员变量一样来访问。例如,一篇文章模型可能包含一个标题属性和内容属性,可以如下:
- $post = new Post();
- $post->title = "Hello, world";
- $post->content = "Something interesting is happening.";
- echo $post->title;
- echo $post->content;
- $post = new Post();
- $post["title"] = "Hello, world";
- $post["content"] = "Something interesting is happening";
- echo $post["title"];
- echo $post["content"];
如果要一次获取模型的所有的属性,可用通过 attributes 属性来得到,下面的例子将得到post模型里面所有的属性,并以name-value的数组形式返回
- $post = Post::findOne(42);
- if ($post) {
- $attributes = $post->attributes;
- var_dump($attributes);
- }
- $post = new Post();
- $attributes = [
- "title" => "Massive assignment example",
- "content" => "Never allow assigning attributes that are not meant to be assigned.",
- ];
- $post->attributes = $attributes;
- var_dump($post->attributes);
4、属性标签
一般情况下在模型里面定义的属性都需要在前台界面显示出来,这个时候有一个对应的友好的文字提示就好了。属性标签就是用来干这个的。
在模型里面定义属性标签很简单,只需要重写yiiaseModel::attributeLabels() 方法即可,它返回的是name-value数组,名称为属性的名称,对应的值即为属性的标签名称。
- // LoginForm has two attributes: username and password
- class LoginForm extends yiiaseModel
- {
- public $username;
- public $password;
- public function attributeLabels()
- {
- return [
- "username" => "Your name",
- "password" => "Your password",
- ];
- }
- }
如果某个属性没有定义对应的标签,Yii会使用yiiaseModel::generateAttributeLabel()方法自动生成对应的标签,
例如username 会生成 Username, orderNumber 生成 Order Number
3、场景
场景说的通俗点,就是不同条件下环境。举个用户注册的例子,普通用户在注册的时候只要用户名、密码、电子邮箱就可以了,而企业用户除了这些外还需要提供企业名称、法人名称、营业执照号什么的,这就是两个不同的场景。
为了让一个模型能使用在不同的场景下面,Yii里面提供了scenarios()方法,返回的也是name-value数组,name为每个不同 的场景,value是一个数组,为对应场景的所用到的属性。
- class User extends yiidbActiveRecord
- {
- public function scenarios()
- {
- return [
- "login" => ["username", "password"],
- "register" => ["username", "email", "password"],
- ];
- }
- }
如果没有在模型中定义场景scenarios(),那么将会使用默认的场景,即所有的属性都将使用。
如果在定义场景的同时还要保持默认的场景可用,那么就得需要调用父类的scenarios()
- class User extends yiidbActiveRecord
- {
- public function scenarios()
- {
- $scenarios = parent::scenarios();
- $scenarios["login"] = ["username", "password"];
- $scenarios["register"] = ["username", "email", "password"];
- return $scenarios;
- }
- }
- ["username", "password", "!secret"]
如果要给模型指定所使用的场景可以用下面的的几个方法
- class EmployeeController extends yiiwebController
- {
- public function actionCreate($id = null)
- {
- // f第一种方法
- $employee = new Employee(["scenario" => "managementPanel"]);
- // 第二种
- $employee = new Employee();
- $employee->scenario = "managementPanel";
- // 第三种
- $employee = Employee::find()->where("id = :id", [":id" => $id])->one();
- if ($employee !== null) {
- $employee->scenario = "managementPanel";
- }
- }
- }
一般来说在表单模型中基本不需要指定场景,因为一个模型对应着一个表单,而默认的场景是返回这个模型里面所有的属性的,而且在对属性的批量赋值方面都是安全的。
4、验证
在通过模型的属性收集用户输入的数据的时候,通常情况下需要验证这些属性的值,例如不能不空、只能是字母等等。如果验证结果有错误就得需要在界面显示出这些错误信息来让用户修改。如
- $model = new LoginForm();
- $model->username = $_POST["username"];
- $model->password = $_POST["password"];
- if ($model->validate()) {
- // 验证成功,所有的属性都满足要求。
- } else {
- $errors = $model->getErrors();
- // 验证出错,得到所有的错误信息。
- }
要定义模型的验证规则的只需要重写rules()。每个验证规则可以作用在多个属性上面,还可以指定这个验证规则所作用的场景。验证器可以用yiivalidatorsValidator的实例来指定
- [
- ["attribute1", "attribute2", ...], //这个验证规则要验证的属性,
- "validator class or alias", //验证器,可以用实例,或者类的名称
- "on" => ["scenario1", "scenario2", ...],//如果指定的使用的场景,则只在这些场景中这个验证规则才有效,否则将作用在所有的场景吧
- "property1" => "value1",//这个以及下面的name-value用来初始化验证器的属性
- "property2" => "value2",
- // ...
- ]
- 规则里面必需至少有一个是活动的属性。
- 规则对当前场景来说必需是可用的。
如果内置的验证器不满足你的需要,你可以在模型类里面通过方法的定义来实现自己的验证器。这个方法将被包装成 InlineValidator对象,并在其它验证规则之前先被调用
你只需要实现对属性的验证逻辑规则,并在验证失败的时候在模型里面添加相应的错误信息。
自定义验证器方法如下
public function myValidator($attribute, $params),其中名称可以随便命名。
下面这个验证器用来验证用户的年龄。
- public function validateAge($attribute, $params)
- {
- $value = $this->$attribute;//$this是当前对象,$attritute是从参数传递过来的属性名称,$value得到这个对象的属性的值。
- if (strtotime($value) > strtotime("now - " . $params["min"] . " years")) {
- $this->addError($attribute, "You must be at least " . $params["min"] . " years old to register for this service.");
- }
- }
- public function rules()
- {
- return [
- // ...
- [["birthdate"], "validateAge", "params" => ["min" => "12"]],
- ];
- }
- [["birthdate"], "validateAge", "params" => ["min" => "12"], "skipOnEmpty" => false],
可以在满员某些条件的情况下才验证属性,例如一个属性的验证需要另外一个属性值(确认密码等),这个时候可以用when关键字来定义
- ["state", "required", "when" => function($model) { return $model->country == Country::USA; }],
- ["stateOthers", "required", "when" => function($model) { return $model->country != Country::USA; }],
- ["mother", "required", "when" => function($model) { return $model->age < 18 && $model->married != true; }],
- public function rules()
- {
- $usa = function($model) { return $model->country == Country::USA; };
- $notUsa = function($model) { return $model->country != Country::USA; };
- $child = function($model) { return $model->age < 18 && $model->married != true; };
- return [
- ["state", "required", "when" => $usa],
- ["stateOthers", "required", "when" => $notUsa], // note that it is not possible to write !$usa
- ["mother", "required", "when" => $child],
- ];
- }
- public function rules()
- {
- $usa = [
- "server-side" => function($model) { return $model->country == Country::USA; },
- "client-side" => "function (attribute, value) {return $("#country").value == "USA";}"
- ];
-
- return [
- ["state", "required", "when" => $usa["server-side"], "whenClient" => $usa["client-side"]],
- ];
- }
在Yii2.0中不像Yii1.x,Yii2.0中的的验证规则和批量赋值是分开的,验证规则在模型中的rules()方法中实现,而批量赋值的安全(safe)属性在scenarios()中实现
- class User extends ActiveRecord
- {
- public function rules()
- {
- return [
- // rule applied when corresponding field is "safe"
- ["username", "string", "length" => [4, 32]],
- ["first_name", "string", "max" => 128],
- ["password", "required"],
- // rule applied when scenario is "signup" no matter if field is "safe" or not
- ["hashcode", "check", "on" => "signup"],
- ];
- }
- public function scenarios()
- {
- return [
- // on signup allow mass assignment of username
- "signup" => ["username", "password"],
- "update" => ["username", "first_name"],
- ];
- }
- }
- $user = User::findOne(42);
- $data = ["password" => "123"];
- $user->attributes = $data;
- print_r($user->attributes);
- $user = User::findOne(42);
- $user->scenario = "signup";
- $data = [
- "username" => "samdark",
- "password" => "123",
- "hashcode" => "test",
- ];
- $user->attributes = $data;
- print_r($user->attributes);
- array(
- "username" => "samdark",
- "first_name" => null,
- "password" => "123",
- "hashcode" => null, // it"s not defined in scenarios method
- )
如果没有定义场景scenarios()的话,
- class User extends ActiveRecord
- {
- public function rules()
- {
- return [
- ["username", "string", "length" => [4, 32]],
- ["first_name", "string", "max" => 128],
- ["password", "required"],
- ];
- }
- }
- $user = User::findOne(42);
- $data = [
- "username" => "samdark",
- "first_name" => "Alexander",
- "last_name" => "Makarov",
- "password" => "123",
- ];
- $user->attributes = $data;
- print_r($user->attributes);
- array(
- "username" => "samdark",
- "first_name" => "Alexander",
- "password" => "123",
- )
- class User extends ActiveRecord
- {
- function rules()
- {
- return [
- ["username", "string", "length" => [4, 32]],
- ["first_name", "string", "max" => 128],
- ["password", "required"],
- ];
- }
- public function scenarios()
- {
- return [
- self::SCENARIO_DEFAULT => ["username", "first_name", "!password"]
- ];
- }
- }
- $user = User::findOne(42);
- $data = [
- "username" => "samdark",
- "first_name" => "Alexander",
- "password" => "123",
- ];
- $user->attributes = $data;
- print_r($user->attributes);
- array(
- "username" => "samdark",
- "first_name" => "Alexander",
- "password" => null, // because of ! before field name in scenarios
- )
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。