2 changed files with 244 additions and 214 deletions
			
			
		@ -0,0 +1,244 @@
					 | 
				
			||||
Model | 
				
			||||
===== | 
				
			||||
 | 
				
			||||
A model in Yii is intended for application data storage and has the following basic features: | 
				
			||||
 | 
				
			||||
- attribute declaration: a model defines what is considered an attribute. | 
				
			||||
- attribute labels: each attribute may be associated with a label for display purpose. | 
				
			||||
- massive attribute assignment. | 
				
			||||
- scenario-based validation. | 
				
			||||
 | 
				
			||||
Models of [[\yii\base\Model]] class are typically used to hold data and corresponding validation rules of complex web forms. | 
				
			||||
The class is also a base for more advanced models with additional functionality such as [Active Record](active-record.md). | 
				
			||||
 | 
				
			||||
Attributes | 
				
			||||
---------- | 
				
			||||
 | 
				
			||||
Attributes store the actual data represented by a model and can | 
				
			||||
be accessed like object member variables. For example, a `Post` model | 
				
			||||
may contain a `title` attribute and a `content` attribute which may be | 
				
			||||
accessed as follows: | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
$post->title = 'Hello, world'; | 
				
			||||
$post->content = 'Something interesting is happening'; | 
				
			||||
echo $post->title; | 
				
			||||
echo $post->content; | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
Since model implements [ArrayAccess](http://php.net/manual/en/class.arrayaccess.php) interface you can use it | 
				
			||||
as array: | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
$post['title'] = 'Hello, world'; | 
				
			||||
$post['content'] = 'Something interesting is happening'; | 
				
			||||
echo $post['title']; | 
				
			||||
echo $post['content']; | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
Default model implementation has a strict rule that all its attributes should be explicitly declared as public and | 
				
			||||
non-static class properties such as the following: | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
// LoginForm has two attributes: username and password | 
				
			||||
class LoginForm extends \yii\base\Model | 
				
			||||
{ | 
				
			||||
	public $username; | 
				
			||||
	public $password; | 
				
			||||
} | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
In order to change it you can override `attributes()` method that returns a list of model attributes. For example, | 
				
			||||
[[\yii\db\ActiveRecord]] class implements attributes as DB table columns: | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
// Post is associated with the tbl_post DB table. | 
				
			||||
// Its attributes correspond to the columns in tbl_post | 
				
			||||
class Post extends \yii\db\ActiveRecord | 
				
			||||
{ | 
				
			||||
	public function table() | 
				
			||||
	{ | 
				
			||||
		return 'tbl_post'; | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
### Attribute labels | 
				
			||||
 | 
				
			||||
Attribute labels are mainly used for display purpose. For example, given an attribute `firstName`, we can declare | 
				
			||||
a label `First Name` which is more user-friendly and can be displayed to end users. | 
				
			||||
 | 
				
			||||
By default an attribute label is generated using [[\yii\base\Model\generateAttributeLabel()]] but the better way is to | 
				
			||||
specify it explicitly like the following: | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
// LoginForm has two attributes: username and password | 
				
			||||
class LoginForm extends \yii\base\Model | 
				
			||||
{ | 
				
			||||
	public $username; | 
				
			||||
	public $password; | 
				
			||||
 | 
				
			||||
	public function attributeLabels() | 
				
			||||
	{ | 
				
			||||
		reuturn array( | 
				
			||||
			'usename' => 'Your name', | 
				
			||||
			'password' => 'Your password', | 
				
			||||
		); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
Scenarios | 
				
			||||
--------- | 
				
			||||
 | 
				
			||||
A model may be used in different scenarios. For example, a `User` model may be used to collect user login inputs, | 
				
			||||
and it may also be used for user registration purpose. For this reason, each model has a property named `scenario` | 
				
			||||
which stores the name of the scenario that the model is currently being used in. As we will explain in the next | 
				
			||||
few sections, the concept of scenario is mainly used in validation and massive attribute assignment. | 
				
			||||
 | 
				
			||||
Associated with each scenario is a list of attributes that are *active* in that particular scenario. For example, | 
				
			||||
in the `login` scenario, only the `username` and `password` attributes are active; while in the `register` scenario, | 
				
			||||
additional attributes such as `email` are *active*. | 
				
			||||
 | 
				
			||||
Possible scenarios should be listed in the `scenarios()` method which returns an array whose keys are the scenario | 
				
			||||
names and whose values are the corresponding active attribute lists. Below is an example: | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
class User extends \yii\db\ActiveRecord | 
				
			||||
{ | 
				
			||||
	public function scenarios() | 
				
			||||
	{ | 
				
			||||
		return array( | 
				
			||||
			'login' => array('username', 'password'), | 
				
			||||
			'register' => array('username', 'email', 'password'), | 
				
			||||
		); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
Sometimes, we want to mark that an attribute is not safe for massive assignment (but we still want it to be validated). | 
				
			||||
We may do so by prefixing an exclamation character to the attribute name when declaring it in `scenarios()`. For example, | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
array('username', 'password', '!secret') | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
Validation | 
				
			||||
---------- | 
				
			||||
 | 
				
			||||
When a model is used to collect user input data via its attributes, it usually needs to validate the affected attributes | 
				
			||||
to make sure they satisfy certain requirements, such as an attribute cannot be empty, an attribute must contain letters | 
				
			||||
only, etc. If errors are found in validation, they may be presented to the user to help him fix the errors. | 
				
			||||
The following example shows how the validation is performed: | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
$model = new LoginForm; | 
				
			||||
$model->username = $_POST['username']; | 
				
			||||
$model->password = $_POST['password']; | 
				
			||||
if ($model->validate()) { | 
				
			||||
	// ...login the user... | 
				
			||||
} else { | 
				
			||||
	$errors = $model->getErrors(); | 
				
			||||
	// ...display the errors to the end user... | 
				
			||||
} | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
The possible validation rules for a model should be listed in its `rules()` method. Each validation rule applies to one | 
				
			||||
or several attributes and is effective in one or several scenarios. A rule can be specified using a validator object - an | 
				
			||||
instance of a [[\yii\validators\Validator]] child class, or an array with the following format: | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
array( | 
				
			||||
	'attribute1, attribute2, ...', | 
				
			||||
	'validator class or alias', | 
				
			||||
	// specifies in which scenario(s) this rule is active. | 
				
			||||
	// if not given, it means it is active in all scenarios | 
				
			||||
	'on' => 'scenario1, scenario2, ...', | 
				
			||||
	// the following name-value pairs will be used | 
				
			||||
	// to initialize the validator properties... | 
				
			||||
	'name1' => 'value1', | 
				
			||||
	'name2' => 'value2', | 
				
			||||
	.... | 
				
			||||
) | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
When `validate()` is called, the actual validation rules executed are determined using both of the following criteria: | 
				
			||||
 | 
				
			||||
- the rules must be associated with at least one active attribute; | 
				
			||||
- the rules must be active for the current scenario. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
### Active Attributes | 
				
			||||
 | 
				
			||||
An attribute is *active* if it is subject to some validations in the current scenario. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
### Safe Attributes | 
				
			||||
 | 
				
			||||
An attribute is *safe* if it can be massively assigned in the current scenario. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Massive Attribute Retrieval and Assignment | 
				
			||||
------------------------------------------ | 
				
			||||
 | 
				
			||||
Attributes can be massively retrieved via the `attributes` property. | 
				
			||||
The following code will return *all* attributes in the `$post` model | 
				
			||||
as an array of name-value pairs. | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
$attributes = $post->attributes; | 
				
			||||
var_dump($attributes); | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
Using the same `attributes` property you can massively assign data from associative array to model attributes: | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
$attributes = array( | 
				
			||||
	'title' => 'Model attributes', | 
				
			||||
	'create_time' => time(), | 
				
			||||
); | 
				
			||||
$post->attributes = $attributes; | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
In the code above we're assigning corresponding data to model fields named as array keys. The key difference from mass | 
				
			||||
retrieval that always works for all attributes is that in order to be assigned an attribute should be **safe** else | 
				
			||||
it will be ignored. | 
				
			||||
 | 
				
			||||
Validation rules and mass assignment | 
				
			||||
------------------------------------ | 
				
			||||
 | 
				
			||||
In Yii2 unlike Yii 1.x validation rules are separated from mass assignment. Validation | 
				
			||||
rules are described in `rules()` method of the model while what's safe for mass | 
				
			||||
assignment is described in `scenarios` method: | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
function rules() | 
				
			||||
{ | 
				
			||||
	return array( | 
				
			||||
		// rule applied when corresponding field is "safe" | 
				
			||||
		array('username', 'length', 'min' => 2), | 
				
			||||
		array('first_name', 'length', 'min' => 2), | 
				
			||||
		array('password', 'required'), | 
				
			||||
 | 
				
			||||
		// rule applied when scenario is "signup" no matter if field is "safe" or not | 
				
			||||
		array('hashcode', 'check', 'on' => 'signup'), | 
				
			||||
	); | 
				
			||||
} | 
				
			||||
 | 
				
			||||
function scenarios() | 
				
			||||
{ | 
				
			||||
	return array( | 
				
			||||
		// on signup allow mass assignment of username | 
				
			||||
		'signup' => array('username', 'password'), | 
				
			||||
		'update' => array('username', 'first_name'), | 
				
			||||
	); | 
				
			||||
} | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
Note that everything is unsafe by default and you can't make field "safe" without specifying scenario. | 
				
			||||
 | 
				
			||||
See also | 
				
			||||
-------- | 
				
			||||
 | 
				
			||||
- [Model validation reference](validation.md) | 
				
			||||
- [[\yii\base\Model]] | 
				
			||||
@ -1,214 +0,0 @@
					 | 
				
			||||
Model | 
				
			||||
===== | 
				
			||||
 | 
				
			||||
Attributes | 
				
			||||
---------- | 
				
			||||
 | 
				
			||||
Attributes store the actual data represented by a model and can | 
				
			||||
be accessed like object member variables. For example, a `Post` model | 
				
			||||
may contain a `title` attribute and a `content` attribute which may be | 
				
			||||
accessed as follows: | 
				
			||||
 | 
				
			||||
~~~php | 
				
			||||
$post->title = 'Hello, world'; | 
				
			||||
$post->content = 'Something interesting is happening'; | 
				
			||||
echo $post->title; | 
				
			||||
echo $post->content; | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
A model should list all its available attributes in the `attributes()` method. | 
				
			||||
 | 
				
			||||
Attributes may be implemented in various ways. The [[\yii\base\Model]] class | 
				
			||||
implements attributes as public member variables of the class, while the | 
				
			||||
[[\yii\db\ActiveRecord]] class implements them as DB table columns. For example, | 
				
			||||
 | 
				
			||||
~~~php | 
				
			||||
// LoginForm has two attributes: username and password | 
				
			||||
class LoginForm extends \yii\base\Model | 
				
			||||
{ | 
				
			||||
	public $username; | 
				
			||||
	public $password; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
// Post is associated with the tbl_post DB table. | 
				
			||||
// Its attributes correspond to the columns in tbl_post | 
				
			||||
class Post extends \yii\db\ActiveRecord | 
				
			||||
{ | 
				
			||||
	public function table() | 
				
			||||
	{ | 
				
			||||
		return 'tbl_post'; | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
 | 
				
			||||
### Attribute Labels | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Scenarios | 
				
			||||
--------- | 
				
			||||
 | 
				
			||||
A model may be used in different scenarios. For example, a `User` model may be | 
				
			||||
used to collect user login inputs, and it may also be used for user registration | 
				
			||||
purpose. For this reason, each model has a property named `scenario` which stores | 
				
			||||
the name of the scenario that the model is currently being used in. As we will explain | 
				
			||||
in the next few sections, the concept of scenario is mainly used in validation and | 
				
			||||
massive attribute assignment. | 
				
			||||
 | 
				
			||||
Associated with each scenario is a list of attributes that are *active* in that | 
				
			||||
particular scenario. For example, in the `login` scenario, only the `username` | 
				
			||||
and `password` attributes are active; while in the `register` scenario, | 
				
			||||
additional attributes such as `email` are *active*. | 
				
			||||
 | 
				
			||||
Possible scenarios should be listed in the `scenarios()` method which returns an array | 
				
			||||
whose keys are the scenario names and whose values are the corresponding | 
				
			||||
active attribute lists. Below is an example: | 
				
			||||
 | 
				
			||||
~~~php | 
				
			||||
class User extends \yii\db\ActiveRecord | 
				
			||||
{ | 
				
			||||
	public function table() | 
				
			||||
	{ | 
				
			||||
		return 'tbl_user'; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public function scenarios() | 
				
			||||
	{ | 
				
			||||
		return array( | 
				
			||||
			'login' => array('username', 'password'), | 
				
			||||
			'register' => array('username', 'email', 'password'), | 
				
			||||
		); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
Sometimes, we want to mark that an attribute is not safe for massive assignment | 
				
			||||
(but we still want it to be validated). We may do so by prefixing an exclamation | 
				
			||||
character to the attribute name when declaring it in `scenarios()`. For example, | 
				
			||||
 | 
				
			||||
~~~php | 
				
			||||
array('username', 'password', '!secret') | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Validation | 
				
			||||
---------- | 
				
			||||
 | 
				
			||||
When a model is used to collect user input data via its attributes, | 
				
			||||
it usually needs to validate the affected attributes to make sure they | 
				
			||||
satisfy certain requirements, such as an attribute cannot be empty, | 
				
			||||
an attribute must contain letters only, etc. If errors are found in | 
				
			||||
validation, they may be presented to the user to help him fix the errors. | 
				
			||||
The following example shows how the validation is performed: | 
				
			||||
 | 
				
			||||
~~~php | 
				
			||||
$model = new LoginForm; | 
				
			||||
$model->username = $_POST['username']; | 
				
			||||
$model->password = $_POST['password']; | 
				
			||||
if ($model->validate()) { | 
				
			||||
	// ...login the user... | 
				
			||||
} else { | 
				
			||||
	$errors = $model->getErrors(); | 
				
			||||
	// ...display the errors to the end user... | 
				
			||||
} | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
The possible validation rules for a model should be listed in its | 
				
			||||
`rules()` method. Each validation rule applies to one or several attributes | 
				
			||||
and is effective in one or several scenarios. A rule can be specified | 
				
			||||
using a validator object - an instance of a [[\yii\validators\Validator]] | 
				
			||||
child class, or an array with the following format: | 
				
			||||
 | 
				
			||||
~~~php | 
				
			||||
array( | 
				
			||||
	'attribute1, attribute2, ...', | 
				
			||||
	'validator class or alias', | 
				
			||||
	// specifies in which scenario(s) this rule is active. | 
				
			||||
	// if not given, it means it is active in all scenarios | 
				
			||||
	'on' => 'scenario1, scenario2, ...', | 
				
			||||
	// the following name-value pairs will be used | 
				
			||||
	// to initialize the validator properties... | 
				
			||||
	'name1' => 'value1', | 
				
			||||
	'name2' => 'value2', | 
				
			||||
	.... | 
				
			||||
) | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
When `validate()` is called, the actual validation rules executed are | 
				
			||||
determined using both of the following criteria: | 
				
			||||
 | 
				
			||||
* the rules must be associated with at least one active attribute; | 
				
			||||
* the rules must be active for the current scenario. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
### Active Attributes | 
				
			||||
 | 
				
			||||
An attribute is *active* if it is subject to some validations in the current scenario. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
### Safe Attributes | 
				
			||||
 | 
				
			||||
An attribute is *safe* if it can be massively assigned in the current scenario. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Massive Access of Attributes | 
				
			||||
---------------------------- | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Massive Attribute Retrieval | 
				
			||||
--------------------------- | 
				
			||||
 | 
				
			||||
Attributes can be massively retrieved via the `attributes` property. | 
				
			||||
The following code will return *all* attributes in the `$post` model | 
				
			||||
as an array of name-value pairs. | 
				
			||||
 | 
				
			||||
~~~php | 
				
			||||
$attributes = $post->attributes; | 
				
			||||
var_dump($attributes); | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Massive Attribute Assignment | 
				
			||||
---------------------------- | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Safe Attributes | 
				
			||||
--------------- | 
				
			||||
 | 
				
			||||
Safe attributes are those that can be massively assigned. For example, | 
				
			||||
 | 
				
			||||
Validation rules and mass assignment | 
				
			||||
------------------------------------ | 
				
			||||
 | 
				
			||||
In Yii2 unlike Yii 1.x validation rules are separated from mass assignment. Validation | 
				
			||||
rules are described in `rules()` method of the model while what's safe for mass | 
				
			||||
assignment is described in `scenarios` method: | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
 | 
				
			||||
function rules() { | 
				
			||||
 return array( | 
				
			||||
  // rule applied when corresponding field is "safe" | 
				
			||||
  array('username', 'length', 'min' => 2), | 
				
			||||
  array('first_name', 'length', 'min' => 2), | 
				
			||||
  array('password', 'required'), | 
				
			||||
 | 
				
			||||
  // rule applied when scenario is "signup" no matter if field is "safe" or not | 
				
			||||
  array('hashcode', 'check', 'on' => 'signup'), | 
				
			||||
 ); | 
				
			||||
} | 
				
			||||
 | 
				
			||||
function scenarios() { | 
				
			||||
 return array( | 
				
			||||
  // on signup allow mass assignment of username | 
				
			||||
  'signup' => array('username', 'password'), | 
				
			||||
  'update' => array('username', 'first_name'), | 
				
			||||
 ); | 
				
			||||
} | 
				
			||||
 | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
Note that everything is unsafe by default and you can't make field "safe" | 
				
			||||
without specifying scenario. | 
				
			||||
					Loading…
					
					
				
		Reference in new issue