Commit f47f6b82 by Nobuo Kihara

Merge branch 'master' of github.com:softark/yii2

parents c81e20b8 afe32293
...@@ -19,7 +19,7 @@ Yii を他のフレームワークと比べるとどうか? ...@@ -19,7 +19,7 @@ Yii を他のフレームワークと比べるとどうか?
あなたが既に他のフレームワークに親しんでいる場合は、Yii を比較するとどうなるのかを知りたいと思うでしょう: あなたが既に他のフレームワークに親しんでいる場合は、Yii を比較するとどうなるのかを知りたいと思うでしょう:
- ほとんどの PHP フレームワーク同様、Yii は MVC (Model-View-Controller) デザインパターンを実装し、このパターンに基いたコードの組織化を促進しています。 - ほとんどの PHP フレームワーク同様、Yii は MVC (Model-View-Controller) デザインパターンを実装し、このパターンに基いたコードの組織化を促進しています。
- Yii は、コードはシンプルかつエレガントに書かれるべきである、という哲学を採用しています。 - Yii は、コードはシンプルかつエレガントに書かれるべきである、という哲学を採用しています。
Yii は、何らかのデザインパターンを厳密に守ることを主たる目的として大袈裟な設計をすることは、決してしようとしません。 Yii は、何らかのデザインパターンを厳密に守ることを主たる目的として大袈裟な設計をすることは、決してしようとしません。
- Yii は、検証済みで直ちに使える多数の機能を提供するフル装備のフレームワークです: - Yii は、検証済みで直ちに使える多数の機能を提供するフル装備のフレームワークです:
......
...@@ -215,7 +215,7 @@ if (YII_ENV_DEV) { ...@@ -215,7 +215,7 @@ if (YII_ENV_DEV) {
#### [[yii\base\Application::controllerMap|controllerMap]] <a name="controllerMap"></a> #### [[yii\base\Application::controllerMap|controllerMap]] <a name="controllerMap"></a>
このプロパティは、コントローラ ID を任意のコントローラクラスに割り付けることを可能にするものです。 このプロパティは、コントローラ ID を任意のコントローラクラスに割り付けることを可能にするものです。
既定では、Yii は [規約](#controllerNamespace) に基いてコントローラ ID をコントローラクラスに割り付けます 既定では、Yii は [規約](#controllerNamespace) に基いてコントローラ ID をコントローラクラスに割り付けます
(例えば、`post` という ID は `app\controllers\PostController` に割り付けられます)。 (例えば、`post` という ID は `app\controllers\PostController` に割り付けられます)。
このプロパティを構成することによって、特定のコントローラに対する規約を破ることが出来ます。 このプロパティを構成することによって、特定のコントローラに対する規約を破ることが出来ます。
下記の例では、`account` は `app\controllers\UserController` に割り付けられ、 下記の例では、`account` は `app\controllers\UserController` に割り付けられ、
...@@ -511,7 +511,7 @@ Yii リリースに含まれているコアコマンドを有効にすべきか ...@@ -511,7 +511,7 @@ Yii リリースに含まれているコアコマンドを有効にすべきか
このイベントがトリガされるときには、アプリケーションのインスタンスは既に構成されて初期化されています。 このイベントがトリガされるときには、アプリケーションのインスタンスは既に構成されて初期化されています。
ですから、イベントメカニズムを使って、リクエスト処理のプロセスに干渉するカスタムコードを挿入するのには、ちょうど良い場所です。 ですから、イベントメカニズムを使って、リクエスト処理のプロセスに干渉するカスタムコードを挿入するのには、ちょうど良い場所です。
例えば、このイベントハンドラの中で、何らかのパラメータに基いて [[yii\base\Application::language]] プロパティを動的にセットすることが出来ます。 例えば、このイベントハンドラの中で、何らかのパラメータに基いて [[yii\base\Application::language]] プロパティを動的にセットすることが出来ます。
### [[yii\base\Application::EVENT_AFTER_REQUEST|EVENT_AFTER_REQUEST]] <a name="afterRequest"></a> ### [[yii\base\Application::EVENT_AFTER_REQUEST|EVENT_AFTER_REQUEST]] <a name="afterRequest"></a>
......
...@@ -450,4 +450,4 @@ class SiteController extends Controller ...@@ -450,4 +450,4 @@ class SiteController extends Controller
* リクエストデータを使って [モデル](structure-models.md) や他のサービスコンポーネントのメソッドを呼ぶことが出来る; * リクエストデータを使って [モデル](structure-models.md) や他のサービスコンポーネントのメソッドを呼ぶことが出来る;
* [ビュー](structure-views.md) を使ってレスポンスを構成することが出来る; * [ビュー](structure-views.md) を使ってレスポンスを構成することが出来る;
* リクエストデータを処理するべきではない - それは [モデル](structure-models.md) において処理されるべきである; * リクエストデータを処理するべきではない - それは [モデル](structure-models.md) において処理されるべきである;
* HTML を埋め込むなどの表示に関わるコードは避けるべきである - それは [views](structure-views.md) で行う方が良い。 * HTML を埋め込むなどの表示に関わるコードは避けるべきである - それは [ビュー](structure-views.md) で行う方が良い。
モデル
======
モデルは [MVC](http://ja.wikipedia.org/wiki/Model_View_Controller) アーキテクチャの一部を成すものです。
これは、業務のデータ、規則、ロジックを表現するオブジェクトです。
モデルクラスは、[[yii\base\Model]] またはその子クラスを拡張することによって作成することが出来ます。
基底クラス [[yii\base\Model]] は数多くの有用な機能をサポートしています。
* [属性](#attributes): 業務のデータを表現し、通常のオブジェクトプロパティや配列要素のようにアクセス出来る。
* [属性のラベル](#attribute-labels): 属性の表示ラベルを規定する。
* [一括代入](#massive-assignment): 一回のステップで複数の属性にデータを投入することをサポートしている。
* [検証規則](#validation-rules): 宣言された検証規則に基いて入力されたデータを確認する。
* [データのエクスポート](#data-exporting): カスタマイズ可能な書式を使ってモデルのデータを配列の形式にエクスポートすることが出来る。
`Model` クラスは、[アクティブレコード](db-active-record.md) のような、更に高度なモデルの基底クラスでもあります。
そういう高度なモデルについての詳細は、関連するドキュメントを参照してください。
> Info|情報: あなたのモデルクラスの基底クラスとして [[yii\base\Model]] を使うことは必須の条件ではありません。
しかしながら、Yii のコンポーネントの多くが [[yii\base\Model]] をサポートするように作られていますので、
通常は [[yii\base\Model]] がモデルの基底クラスとして推奨されます。
## 属性<a name="attributes"></a>
モデルは業務のデータを *属性* の形式で表現します。
全ての属性はそれぞれパブリックにアクセス可能なモデルのプロパティと同様なものです。
メソッド [[yii\base\Model::attributes()]] が、モデルがどのような属性を持つかを規定します。
属性に対しては、通常のオブジェクトプロパティにアクセスするのと同じようにして、アクセスすることが出来ます。
```php
$model = new \app\models\ContactForm;
// "name" は ContactForm の属性
$model->name = 'example';
echo $model->name;
```
また、配列の要素にアクセスするようして、属性にアクセスすることも出来ます。
これは、[[yii\base\Model]] が [ArrayAccess インターフェイス](http://php.net/manual/ja/class.arrayaccess.php)[ArrayIterator クラス](http://jp2.php.net/manual/ja/class.arrayiterator.php) をサポートしているおかげです。
```php
$model = new \app\models\ContactForm;
// 配列要素のように属性にアクセスする
$model['name'] = 'example';
echo $model['name'];
// 属性に反復アクセスする
foreach ($model as $name => $value) {
echo "$name: $value\n";
}
```
### 属性を定義する<a name="defining-attributes"></a>
あなたのモデルが [[yii\base\Model]] を直接に拡張するものである場合、既定によって、全ての *static でない public な* メンバ変数は属性となります。
例えば、次に示す `ContactForm` モデルは4つの属性を持ちます: すなわち、`name``email``subject`、そして、`body` です。
この `ContactForm` モデルは、HTML フォームから受け取る入力データを表現するために使われます。
```php
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()` などのマジックメソッドをオーバーライドして、
属性が通常のオブジェクトプロパティと同じようにアクセス出来るようにする必要があるかもしれないことに注意してください。
### 属性のラベル <a name="attribute-labels"></a>
属性の値を表示したり、入力してもらったりするときに、属性と関連付けられたラベルを表示する必要があることがよくあります。
例えば、`firstName` という名前の属性を考えたとき、入力フォームやエラーメッセージのような箇所でエンドユーザに表示するときは、もっとユーザフレンドリーな `First Name` というラベルを表示したいと思うでしょう。
[[yii\base\Model::getAttributeLabel()]] を呼ぶことによって属性のラベルを得ることが出来ます。例えば、
```php
$model = new \app\models\ContactForm;
// "Name" を表示する
echo $model->getAttributeLabel('name');
```
既定では、属性のラベルは属性の名前から自動的に生成されます。
ラベルの生成は [[yii\base\Model::generateAttributeLabel()]] というメソッドによって行われます。
このメソッドは、キャメルケースの変数名を複数の単語に分割し、各単語の最初の文字を大文字にします。
例えば、`username``Username` となり、`firstName``First Name` となります。
自動的に生成されるラベルを使用したくない場合は、[[yii\base\Model::attributeLabels()]] をオーバーライドして、
属性のラベルを明示的に宣言することが出来ます。例えば、
```php
namespace app\models;
use yii\base\Model;
class ContactForm extends Model
{
public $name;
public $email;
public $subject;
public $body;
public function attributeLabels()
{
return [
'name' => 'Your name',
'email' => 'Your email address',
'subject' => 'Subject',
'body' => 'Content',
];
}
}
```
複数の言語をサポートするアプリケーションでは、属性のラベルを翻訳したいと思うでしょう。
これも、以下のように、[[yii\base\Model::attributeLabels()|attributeLabels()]] の中で行うことが出来ます:
```php
public function attributeLabels()
{
return [
'name' => \Yii::t('app', 'Your name'),
'email' => \Yii::t('app', 'Your email address'),
'subject' => \Yii::t('app', 'Subject'),
'body' => \Yii::t('app', 'Content'),
];
}
```
さらに進んで、条件に従って属性のラベルを定義しても構いません。例えば、モデルが使用される
[シナリオ](#scenarios) に基づいて、同じ属性に対して違うラベルを返すことことが出来ます。
> Info|情報: 厳密に言えば、属性のラベルは [ビュー](structure-views.md) の一部を成すものです。
しかし、たいていの場合、モデルの中でラベルを宣言する方が便利が良く、
結果としてクリーンで再利用可能なコードになります。
## シナリオ<a name="scenarios"></a>
モデルはさまざまに異なる *シナリオ* で使用されます。
例えば、`User` モデルはユーザログインの入力を収集するために使われますが、同時に、ユーザ登録の目的でも使われます。
異なるシナリオの下では、モデルが使用する業務のルールとロジックも異なるでしょう。
例えば、`email` 属性はユーザ登録の際には必須とされるかも知れませんが、ログインの際にはそうではないでしょう。
モデルは [[yii\base\Model::scenario]] プロパティを使って、自身が使われているシナリオを追跡します。
既定では、モデルは `default` という単一のシナリオのみをサポートします。
次のコードは、モデルのシナリオを設定する二つの方法を示すものです:
```php
// プロパティとしてシナリオをセットする
$model = new User;
$model->scenario = 'login';
// シナリオはコンフィギュレーションでセットされる
$model = new User(['scenario' => 'login']);
```
既定では、モデルによってサポートされるシナリオは、モデルで宣言されている [検証規則](#validation-rules) によって決定されます。
しかし、次のように、[[yii\base\Model::scenarios()]] メソッドをオーバーライドして、この動作をカスタマイズすることが出来ます:
```php
namespace app\models;
use yii\db\ActiveRecord;
class User extends ActiveRecord
{
public function scenarios()
{
return [
'login' => ['username', 'password'],
'register' => ['username', 'email', 'password'],
];
}
}
```
> Info|情報: 上記の例と後続の例では、モデルクラスは [[yii\db\ActiveRecord]] を拡張するものとなっています。
というのは、複数のシナリオの使用は、通常、[アクティブレコード](db-active-record.md) クラスで発生するからです。
`seanarios()` メソッドは、キーがシナリオの名前であり、値が対応する *アクティブな属性* である配列を返します。
アクティブな属性とは、[一括代入](#massive-assignment) することが出来て、[検証](#validation-rules) の対象になる属性です。
上記の例では、`login` シナリオにおいては `username``password` の属性がアクティブであり、一方、
`register` シナリオにおいては、`username``password` に加えて `email` もアクティブです。
`scenarios()` の既定の実装は、検証規則の宣言メソッドである [[yii\base\Model::rules()]] に現れる全てのシナリオを返すものです。
`scenarios()` をオーバーライドするときに、デフォルトのシナリオに加えて新しいシナリオを導入したい場合は、
次のようなコードを書きます:
```php
namespace app\models;
use yii\db\ActiveRecord;
class User extends ActiveRecord
{
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios['login'] = ['username', 'password'];
$scenarios['register'] = ['username', 'email', 'password'];
return $scenarios;
}
}
```
シナリオの機能は、主として、[検証](#validation-rules)[属性の一括代入](#massive-assignment) によって使用されます。
しかし、他の目的に使うことも可能です。例えば、現在のシナリオに基づいて異なる [属性のラベル](#attribute-labels) を宣言することも出来ます。
## 検証規則<a name="validation-rules"></a>
モデルのデータをエンドユーザから受け取ったときは、データを検証して、それが一定の規則 (*検証規則*、あるいは、いわゆる *ビジネスルール*) を満たしていることを確認しなければなりません。
`ContactForm` モデルを例に挙げるなら、全ての属性が空っぽではなく、`email` 属性が有効なメールアドレスを含んでいることを確認したいでしょう。
いずれかの属性の値が対応するビジネスルールを満たしていないときは、ユーザがエラーを訂正するのを助ける適切なエラーメッセージが表示されるべきです。
受信したデータを検証するために、[[yii\base\Model::validate()]] を呼ぶことが出来ます。
このメソッドは、[[yii\base\Model::rules()]] で宣言された検証規則を使って、該当するすべての属性を検証します。
エラーが見つからなければ、メソッドは true を返します。そうでなければ、[[yii\base\Model::errors]]
にエラーを保存して、false を返します。例えば、
```php
$model = new \app\models\ContactForm;
// モデルの属性にユーザの入力を代入する
$model->attributes = \Yii::$app->request->post('ContactForm');
if ($model->validate()) {
// すべての入力値は有効である
} else {
// 検証が失敗: $errors はエラーメッセージを含む配列
$errors = $model->errors;
}
```
モデルに関連付けられた検証規則を宣言するためには、[[yii\base\Model::rules()]] メソッドをオーバーライドして、
モデルの属性が満たすべき規則を返すようにします。
次の例は、`ContactForm` モデルのために宣言された検証規則を示します:
```php
public function rules()
{
return [
// name、email、subject、body の属性が必須
[['name', 'email', 'subject', 'body'], 'required'],
// email 属性は、有効なメールアドレスでなければならない
['email', 'email'],
];
}
```
一個の規則は、一個または複数の属性を検証するために使うことが出来ます。
また、一個の属性は、一個または複数の規則によって検証することが出来ます。
検証規則をどのように宣言するかについて、更なる詳細は [入力を検証する](input-validation.md) の節を参照してください。
時として、特定の [シナリオ](#scenarios) にのみ適用される規則が必要になるでしょう。そのためには、下記のように、
規則に `on` プロパティを指定することが出来ます:
```php
public function rules()
{
return [
// "register" シナリオでは、username、email、password のすべてが必須
[['username', 'email', 'password'], 'required', 'on' => 'register'],
// "login" シナリオでは、username と password が必須
[['username', 'password'], 'required', 'on' => 'login'],
];
}
```
`on` プロパティを指定しない場合は、その規則は全てのシナリオに適用されることになります。
現在の [[yii\base\Model::scenario|シナリオ]] に適用可能な規則は *アクティブな規則* と呼ばれます。
属性が検証されるのは、それが `scenarios()` の中でアクティブな属性であると宣言されており、
かつ、`rules()` の中で宣言されている一つまたは複数のアクティブな規則と関連付けられている場合であり、また、そのような場合だけです。
## 一括代入<a name="massive-assignment"></a>
一括代入は、一行のコードを書くだけで、ユーザの入力したデータをモデルに投入できる便利な方法です。
一括代入は、入力されたデータを [[yii\base\Model::$attributes]] に直接に代入することによって、モデルの属性にデータを投入します。
次の二つのコード断片は等価であり、どちらもエンドユーザから送信されたフォームのデータを `ContactForm` モデルの属性に割り当てようとするものです。
明らかに、一括代入を使う前者の方が、後者よりも明瞭で間違いも起こりにくいでしょう:
```php
$model = new \app\models\ContactForm;
$model->attributes = \Yii::$app->request->post('ContactForm');
```
```php
$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;
```
### 安全な属性<a name="safe-attributes"></a>
一括代入は、いわゆる *安全な属性*、すなわち、モデルの現在の [[yii\base\Model::scenario|シナリオ]]
用に [[yii\base\Model::scenarios()]] にリストされている属性に対してのみ適用されます。
例えば、`User` モデルが次のようなシナリオ宣言を持っている場合において、現在のシナリオが `login` であるときは、`username``password` のみが一括代入が可能です。その他の属性はいっさい触れられません。
```php
public function scenarios()
{
return [
'login' => ['username', 'password'],
'register' => ['username', 'email', 'password'],
];
}
```
> Info|情報: 一括代入が安全な属性に対してのみ適用されるのは、どの属性がエンドユーザのデータによって
修正されうるかを制御する必要があるからです。
例えば、`User` モデルに、ユーザに割り当てられる権限を決定する `permission` という属性がある場合、
この属性が修正できるのは、管理者がバックエンドのインターフェイスを通じてする時だけに制限したいでしょう。
[[yii\base\Model::scenarios()]] の既定の実装は [[yii\base\Model::rules()]] に現われる全てのシナリオと属性を返すものです。
従って、このメソッドをオーバーライドしない場合は、アクティブな検証規則のどれかに出現する限り、その属性は安全である、ということになります。
このため、実際に検証することなく属性を安全であると宣言できるように、`safe` というエイリアスを与えられた特別なバリデータが提供されています。例えば、次の規則は `title``description` の両方が安全な属性であると宣言しています。
```php
public function rules()
{
return [
[['title', 'description'], 'safe'],
];
}
```
### 安全でない属性<a name="unsafe-attributes"></a>
上記で説明したように、[[yii\base\Model::scenarios()]] メソッドは二つの目的を持っています:
すなわち、どの属性が検証されるべきかを決めることと、どの属性が安全であるかを決めることです。
めったにない場合として、属性を検証する必要はあるが、安全であるという印は付けたくない、ということがあります。
そういう時は、下の例の `secret` 属性のように、`scenarios()` の中で宣言するときに属性の名前の前に感嘆符
`!` を前置することが出来ます:
```php
public function scenarios()
{
return [
'login' => ['username', 'password', '!secret'],
];
}
```
このモデルが `login` シナリオにある場合、三つの属性は全て検証されます。しかし、`username`
`password` の属性だけが一括代入が可能です。`secret` 属性に入力値を割り当てるためには、
下記のように明示的に実行する必要があります。
```php
$model->secret = $secret;
```
## データのエクスポート <a name="data-exporting"></a>
モデルを他の形式にエクスポートする必要が生じることはよくあります。例えば、一群のモデルを JSON や
Excel 形式に変換したい場合があるでしょう。
エクスポートのプロセスは二つの独立したステップに分割することが出来ます。
最初のステップで、モデルは配列に変換されます。そして第二のステップで、配列が目的の形式に変換されます。
あなたは最初のステップだけに注力しても構いません。と言うのは、第二のステップは汎用的なデータフォーマッタ、
例えば [[yii\web\JsonResponseFormatter]] によって達成できるからです。
モデルを配列に変換する最も簡単な方法は、[[yii\base\Model::$attributes]] プロパティを使うことです。
例えば、
```php
$post = \app\models\Post::findOne(100);
$array = $post->attributes;
```
既定によって、[[yii\base\Model::$attributes]] プロパティは [[yii\base\Model::attributes()]] で宣言されている *全て* の属性の値を返します。
モデルを配列に変換するためのもっと柔軟で強力な方法は、[[yii\base\Model::toArray()]] メソッドを使うことです。
このメソッドの既定の動作は [[yii\base\Model::$attributes]] のそれと同じものです。
しかしながら、このメソッドを使うと、どのデータ項目 (*フィールド* と呼ばれます) を結果の配列に入れるか、
そして、その項目にどのような書式を適用するかを選ぶことが出来ます。
実際、[レスポンスの書式設定](rest-response-formatting.md) で説明されているように、
RESTFul ウェブサービスの開発においては、これがモデルをエクスポートする既定の方法となっています。
### フィールド<a name="fields"></a>
フィールドとは、単に、モデルの [[yii\base\Model::toArray()]] メソッドを呼ぶことによって取得される配列の中の、
名前付きの要素のことです。
既定では、フィールドの名前は属性の名前と等しいものになります。しかし、この既定の動作は、
[[yii\base\Model::fields()|fields()]] および/または [[yii\base\Model::extraFields()|extraFields()]] メソッドをオーバーライドして、変更することが出来ます。
どちらも、フィールド定義のリストを返すべきメソッドです。
`fields()` によって定義されたフィールドは、デフォルトフィールドです。
すなわち、`toArray()` が、既定ではこれらのフィールドを返すということを意味します。
`extraFields()` メソッドは、`$expand` パラメータによって指定する限りにおいて `toArray()` によって返され得る、追加のフィールドを定義します。
例として、次のコードは、`fields()` で定義された全てのフィールドと、
(`extraFields()` で定義されていれば) `prettyName``fullAddress` フィールドを返すものです。
```php
$array = $model->toArray([], ['prettyName', 'fullAddress']);
```
`fields()` をオーバーライドして、フィールドを追加、削除、リネーム、再定義することが出来ます。
`fields()` の返り値は配列でなければなりません。配列のキーはフィールド名であり、
配列の値は対応するフィールド定義です。フィールド定義には、プロパティ/属性の名前か、または、対応するフィールドの値を返す無名関数を使うことが出来ます。
フィールド名がそれを定義する属性名と同一であるという特殊な場合においては、配列のキーを省略することが出来ます。
例えば、
```php
// 明示的に全てのフィールドをリストする方法。(API の後方互換性を保つために) DB テーブルやモデル属性の
// 変更がフィールドの変更を引き起こさないことを保証したい場合に適している。
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;
}
```
> Warning|警告: 既定ではモデルの全ての属性がエクスポートされる配列に含まれるため、データを精査して、
> 慎重に扱うべき情報が含まれていないことを確認すべきです。そういう情報がある場合は、
> `fields()` をオーバーライドして、除去すべきです。上記の例では、`auth_key`、`password_hash`
> および `password_reset_token` を選んで除去しています。
## 最善の慣行<a name="best-practices"></a>
モデルは、業務のデータ、規則、ロジックを表わす中心的なオブジェクトです。
モデルは、他の場所で再利用する必要がよくあります。
良く設計されたアプリケーションでは、通常、モデルは [コントローラ](structure-controllers.md) よりもはるかに重いものになります。
要約すると、モデルは、
* ビジネスデータを表現する属性を含むことが出来る;
* データの有効性と整合性を保証する検証規則を含むことが出来る;
* ビジネスロジックを実装するメソッドを含むことが出来る;
* リクエスト、セッション、または他の環境データに直接アクセスするべきではない。
これらのデータは、[コントローラ](structure-controllers.md) によってモデルに注入されるべきである;
* HTML を埋め込むなどの表示用のコードは避けるべきである - これは [ビュー](structure-views.md) で行う方が良い;
* あまりに多くの [シナリオ](#scenarios) を単一のモデルで持つことは避ける。
大規模で複雑なシステムを開発するときには、たいてい、上記の最後にあげた推奨事項を考慮するのが良いでしょう。
そういうシステムでは、モデルは数多くの場所で使用され、それに従って、数多くの規則セットやビジネスロジックを含むため、非常に大きくて重いものになり得ます。
コードの一ヶ所に触れるだけで数ヶ所の違った場所に影響が及ぶため、ついには、モデルのコードの保守が悪夢になってしまうこともよくあります。
モデルのコードの保守性を高めるために、以下の戦略をとることが出来ます:
* 異なる [アプリケーション](structure-applications.md)[モジュール](structure-modules.md)
によって共有される一連の基底モデルクラスを定義する。
これらのモデルクラスは、すべてで共通に使用される最小限の規則セットとロジックのみを含むべきである。
* モデルを使用するそれぞれの [アプリケーション](structure-applications.md) または [モジュール](structure-modules.md) において、
対応する基底モデルクラスから拡張した具体的なモデルクラスを定義する。
この具体的なモデルクラスが、そのアプリケーションやモジュールに固有の規則やロジックを含むべきである。
例えば、[アドバンストアプリケーションテンプレート](tutorial-advanced-app.md) の中で、
基底モデルクラス `common\models\Post` を定義することが出来ます。
次に、フロントエンドアプリケーションにおいては、`common\models\Post` から拡張した具体的なモデルクラス
`frontend\models\Post` を定義して使います。
また、バックエンドアプリケーションにおいても、同様に、`backend\models\Post` を定義します。
この戦略を取ると、`frontend\models\Post` の中のコードはフロントエンドアプリケーション固有のものであると保証することが出来ます。
そして、フロントエンドのコードにどのような変更を加えても、バックエンドアプリケーションを壊すかもしれないと心配する必要がなくなります。
...@@ -29,7 +29,7 @@ if ($this->beginCache($id)) { ...@@ -29,7 +29,7 @@ if ($this->beginCache($id)) {
### Срок хранения <a name="duration"></a> ### Срок хранения <a name="duration"></a>
Наверное, наиболее часто используемым параметром является [[yii\widgets\FragmentCache::duration|duration]]. Наверное, наиболее часто используемым параметром является [[yii\widgets\FragmentCache::duration|duration]].
Он определяет какое количество секунд содержимое будет оставаться действительным (корректным). Следующий код помещает фрагмент в кэш не более, чем на час:: Он определяет какое количество секунд содержимое будет оставаться действительным (корректным). Следующий код помещает фрагмент в кэш не более, чем на час:
```php ```php
if ($this->beginCache($id, ['duration' => 3600])) { if ($this->beginCache($id, ['duration' => 3600])) {
...@@ -83,7 +83,7 @@ if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) { ...@@ -83,7 +83,7 @@ if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) {
### Переключение кэширования <a name="toggling-caching"></a> ### Переключение кэширования <a name="toggling-caching"></a>
Иногда может потребоваться включать кеширование фрагментов только для определённых условий. Например, страницу с формой мы хотим кэшировать только тогда, когда обращение к ней произошло впервые (посредством GET запроса). Любое последующее отображение формы (посредством POST запроса) не должно быть кэшировано, потому что может содержать данные, введённые пользователем. Для этого мы задаём параметр [[yii\widgets\FragmentCache::enabled|enabled]]: Иногда может потребоваться включать кэширование фрагментов только для определённых условий. Например, страницу с формой мы хотим кэшировать только тогда, когда обращение к ней произошло впервые (посредством GET запроса). Любое последующее отображение формы (посредством POST запроса) не должно быть кэшировано, потому что может содержать данные, введённые пользователем. Для этого мы задаём параметр [[yii\widgets\FragmentCache::enabled|enabled]]:
```php ```php
if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) { if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) {
...@@ -117,7 +117,7 @@ if ($this->beginCache($id1)) { ...@@ -117,7 +117,7 @@ if ($this->beginCache($id1)) {
} }
``` ```
Параметры кэширования могут быть различными для вложенных кэшей. Например, внутренний и внешний кэши в вышеприведённом примере могут иметь разные сроки хранения. Даже когда данные внешнего кэша уже не являются актуальными, внутренний кеш может содержать актуальный фрагмент. Тем не менее, обратное не верно. Если внешний кэш актуален, данные будут отдаваться из него даже если внутренний кэш содержит устаревшие данные. Следует проявлять осторожность при выставлении срока хранения и задания зависимостей для вложенных кэшей. В противном случае вы можете получить устаревшие данные. Параметры кэширования могут быть различными для вложенных кэшей. Например, внутренний и внешний кэши в вышеприведённом примере могут иметь разные сроки хранения. Даже когда данные внешнего кэша уже не являются актуальными, внутренний кэш может содержать актуальный фрагмент. Тем не менее, обратное не верно. Если внешний кэш актуален, данные будут отдаваться из него даже если внутренний кэш содержит устаревшие данные. Следует проявлять осторожность при выставлении срока хранения и задания зависимостей для вложенных кэшей. В противном случае вы можете получить устаревшие данные.
## Динамическое содержимое <a name="dynamic-content"></a> ## Динамическое содержимое <a name="dynamic-content"></a>
......
...@@ -104,7 +104,7 @@ Cache-Control: public, max-age=3600 ...@@ -104,7 +104,7 @@ Cache-Control: public, max-age=3600
## Ограничитель кэша сессий <a name="session-cache-limiter"></a> ## Ограничитель кэша сессий <a name="session-cache-limiter"></a>
Когда на странице используются сессии, PHP автоматически отправляет некоторые связанные с кэшем HTTP заголовки, определённые в настройке `session.cache_limiter` в php.ini. Эти заголовки могут вмешиваться или отключать кэширование, которое вы ожидаете от `HttpCache`. Чтобы предотвратить эту проблему, по-умолчанию `HttpCache` будет автоматически отключать отправку этих заголовков. Если вы хотите изменить это поведение, вы должны настроить свойство [[yii\filters\HttpCache::sessionCacheLimiter]]. Это свойство может принимать строковое значение, включая `public`, `private`, `private_no_expire` и `nocache`. Пожалуйста, обратитесь к руководству PHP о [session_cache_limiter()](http://www.php.net/manual/en/function.session-cache-limiter.php) Когда на странице используются сессии, PHP автоматически отправляет некоторые связанные с кэшем HTTP заголовки, определённые в настройке `session.cache_limiter` в php.ini. Эти заголовки могут вмешиваться или отключать кэширование, которое вы ожидаете от `HttpCache`. Чтобы предотвратить эту проблему, по умолчанию `HttpCache` будет автоматически отключать отправку этих заголовков. Если вы хотите изменить это поведение, вы должны настроить свойство [[yii\filters\HttpCache::sessionCacheLimiter]]. Это свойство может принимать строковое значение, включая `public`, `private`, `private_no_expire` и `nocache`. Пожалуйста, обратитесь к руководству PHP о [session_cache_limiter()](http://www.php.net/manual/en/function.session-cache-limiter.php)
для объяснения этих значений. для объяснения этих значений.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
================= =================
Кэширование страниц — это кэширование всего содержимого страницы на стороне сервера. Позже, когда эта страница Кэширование страниц — это кэширование всего содержимого страницы на стороне сервера. Позже, когда эта страница
будет снова запрошена, сервер вернет её из кэша вместо того что бы генерировать её заново. будет снова запрошена, сервер вернет её из кэша вместо того чтобы генерировать её заново.
Кэширование страниц осуществляется при помощи [фильтра действия](structure-filters.md) [[yii\filters\PageCache]] и Кэширование страниц осуществляется при помощи [фильтра действия](structure-filters.md) [[yii\filters\PageCache]] и
может быть использовано в классе контроллера следующим образом: может быть использовано в классе контроллера следующим образом:
...@@ -27,7 +27,7 @@ public function behaviors() ...@@ -27,7 +27,7 @@ public function behaviors()
} }
``` ```
Приведённый код задействует кэширование только для действия `index`. Содержимое страницы кешируется максимум на 60 секунд Приведённый код задействует кэширование только для действия `index`. Содержимое страницы кэшируется максимум на 60 секунд
и варьируется в зависимости от текущего языка приложения. Кэшированная страница должна быть признана просроченной, если и варьируется в зависимости от текущего языка приложения. Кэшированная страница должна быть признана просроченной, если
общее количество постов изменилось. общее количество постов изменилось.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
======== ========
Настройки широко используются в Yii при создании новых объектов или при инициализации уже существующих объектов. Настройки широко используются в Yii при создании новых объектов или при инициализации уже существующих объектов.
Обычно настройки включают в себя названия классов создаваемых объектов и список первоначальных значений Обычно настройки включают в себя названия классов создаваемых объектов и список первоначальных значений,
которые должны быть присвоены [свойствам](concept-properties.md) объекта. Также в настройках можно указать список которые должны быть присвоены [свойствам](concept-properties.md) объекта. Также в настройках можно указать список
[обработчиков событий](concept-events.md) объекта, и/или список [поведений](concept-behaviors.md) объекта. [обработчиков событий](concept-events.md) объекта, и/или список [поведений](concept-behaviors.md) объекта.
......
...@@ -98,7 +98,7 @@ $container = new \yii\di\Container; ...@@ -98,7 +98,7 @@ $container = new \yii\di\Container;
// регистрация имени класса, как есть. это может быть пропущено. // регистрация имени класса, как есть. это может быть пропущено.
$container->set('yii\db\Connection'); $container->set('yii\db\Connection');
// регистраци интерфейса // регистрация интерфейса
// Когда класс зависит от интерфейса, соответствующий класс // Когда класс зависит от интерфейса, соответствующий класс
// будет использован в качестве зависимости объекта // будет использован в качестве зависимости объекта
$container->set('yii\mail\MailInterface', 'yii\swiftmailer\Mailer'); $container->set('yii\mail\MailInterface', 'yii\swiftmailer\Mailer');
...@@ -172,7 +172,7 @@ $engine = $container->get('app\components\SearchEngine', [$apiKey], ['type' => 1 ...@@ -172,7 +172,7 @@ $engine = $container->get('app\components\SearchEngine', [$apiKey], ['type' => 1
``` ```
За кулисами, контейнер внедрения зависимостей делает гораздо больше работы, чем просто создание нового объекта. За кулисами, контейнер внедрения зависимостей делает гораздо больше работы, чем просто создание нового объекта.
Прежде всего, контейнер, осмотрит конструктор класса, что бы узнать имя зависимого класса или интерфейса, а затем автоматически разрешит эти зависимости рекурсивно. Прежде всего, контейнер, осмотрит конструктор класса, чтобы узнать имя зависимого класса или интерфейса, а затем автоматически разрешит эти зависимости рекурсивно.
Следующий код демонстрирует более сложный пример. Класс `UserLister` зависит от объекта, реализующего интерфейс `UserFinderInterface`; класс `UserFinder` реализует этот интерфейс и зависит от Следующий код демонстрирует более сложный пример. Класс `UserLister` зависит от объекта, реализующего интерфейс `UserFinderInterface`; класс `UserFinder` реализует этот интерфейс и зависит от
объекта `Connection`. Все эти зависимости были объявлены через тип подсказки параметров конструктора класса. объекта `Connection`. Все эти зависимости были объявлены через тип подсказки параметров конструктора класса.
...@@ -240,7 +240,7 @@ $lister = new UserLister($finder); ...@@ -240,7 +240,7 @@ $lister = new UserLister($finder);
Yii создаёт контейнер внедрения зависимостей когда вы подключаете файл `Yii.php` во [входном скрипте](structure-entry-scripts.md) Yii создаёт контейнер внедрения зависимостей когда вы подключаете файл `Yii.php` во [входном скрипте](structure-entry-scripts.md)
вашего приложения. Контейнер внедрения зависимостей доступен через [[Yii::$container]]. При вызове [[Yii::createObject()]], вашего приложения. Контейнер внедрения зависимостей доступен через [[Yii::$container]]. При вызове [[Yii::createObject()]],
метод на самом деле вызовет метод контейнера [[yii\di\Container::get()|get()]], что бы создать новый объект. метод на самом деле вызовет метод контейнера [[yii\di\Container::get()|get()]], чтобы создать новый объект.
Как упомянуто выше, контейнер внедрения зависимостей автоматически разрешит зависимости (если таковые имеются) и внедрит их в только что созданный объект. Как упомянуто выше, контейнер внедрения зависимостей автоматически разрешит зависимости (если таковые имеются) и внедрит их в только что созданный объект.
Поскольку Yii использует [[Yii::createObject()]] в большей части кода своего ядра для создания новых объектов, это означает, Поскольку Yii использует [[Yii::createObject()]] в большей части кода своего ядра для создания новых объектов, это означает,
что вы можете настроить глобальные объекты, имея дело с [[Yii::$container]]. что вы можете настроить глобальные объекты, имея дело с [[Yii::$container]].
...@@ -307,7 +307,7 @@ class HotelController extends Controller ...@@ -307,7 +307,7 @@ class HotelController extends Controller
Итог <a name="summary"></a> Итог <a name="summary"></a>
------- -------
Как dependency injection, так и [service locator](concept-service-locator.md) являются популярными паттернами проектирования, которые позволяют Как dependency injection, так и [service locator](concept-service-locator.md) являются популярными паттернами проектирования, которые позволяют
создавать программное обеспечение в слабосвязаной и более тестируемой манере. создавать программное обеспечение в слабосвязанной и более тестируемой манере.
Мы настоятельно рекомендуем к прочтению Мы настоятельно рекомендуем к прочтению
[статью Мартина Фаулера](http://martinfowler.com/articles/injection.html), для более глубокого понимания dependency injection и service locator. [статью Мартина Фаулера](http://martinfowler.com/articles/injection.html), для более глубокого понимания dependency injection и service locator.
......
...@@ -445,7 +445,7 @@ Yii 2.0 осуществляет жадную загрузку связи не ...@@ -445,7 +445,7 @@ Yii 2.0 осуществляет жадную загрузку связи не
$customers = Customer::find()->asArray()->all(); $customers = Customer::find()->asArray()->all();
``` ```
Ещё одно изменение связано с тем, что вы больше не можете определять значения по-умолчанию через public свойства. Ещё одно изменение связано с тем, что вы больше не можете определять значения по умолчанию через public свойства.
Вы должны установить их в методе `init` вашего класса, если это требуется. Вы должны установить их в методе `init` вашего класса, если это требуется.
```php ```php
......
...@@ -10,7 +10,7 @@ Yii – это высокопроизводительный компонентн ...@@ -10,7 +10,7 @@ Yii – это высокопроизводительный компонентн
------------------------------------------ ------------------------------------------
Yii – это универсальный фреймворк и может быть задействован во всех типах веб приложений. Благодаря его компонентной Yii – это универсальный фреймворк и может быть задействован во всех типах веб приложений. Благодаря его компонентной
структуре и отличной поддержке кеширования, фреймворк особенно подходит для разработки таких крупных проектов как структуре и отличной поддержке кэширования, фреймворк особенно подходит для разработки таких крупных проектов как
порталы, форумы, CMS, магазины или RESTful-приложения. порталы, форумы, CMS, магазины или RESTful-приложения.
...@@ -23,7 +23,7 @@ Yii – это универсальный фреймворк и может бы ...@@ -23,7 +23,7 @@ Yii – это универсальный фреймворк и может бы
- Yii придерживается философии простого и элегантного кода не пытаясь усложнять дизайн только ради следования каким-либо - Yii придерживается философии простого и элегантного кода не пытаясь усложнять дизайн только ради следования каким-либо
шаблонам проектирования. шаблонам проектирования.
- Yii является full-stack фреймворком и включает в себя проверенные и хорошо зарекомендовавшие себя возможности, такие как - Yii является full-stack фреймворком и включает в себя проверенные и хорошо зарекомендовавшие себя возможности, такие как
ActiveRecord для реляционных и NoSQL баз данных, поддержку REST API, многоуровневое кеширование и другие. ActiveRecord для реляционных и NoSQL баз данных, поддержку REST API, многоуровневое кэширование и другие.
- Yii отлично расширяем. Вы можете настроить или заменить практически любую часть основного кода. Используя архитектуру расширений легко делиться кодом или использовать код сообщества. - Yii отлично расширяем. Вы можете настроить или заменить практически любую часть основного кода. Используя архитектуру расширений легко делиться кодом или использовать код сообщества.
- Одна из главных целей Yii – производительность. - Одна из главных целей Yii – производительность.
......
...@@ -5,7 +5,7 @@ Yii включает полноценный набор средств для у ...@@ -5,7 +5,7 @@ Yii включает полноценный набор средств для у
В частности это следующие возможности: В частности это следующие возможности:
* Быстрое создание прототипов с поддержкой распространенных API к [Active Record](db-active-record.md); * Быстрое создание прототипов с поддержкой распространенных API к [Active Record](db-active-record.md);
* Настройка формата ответа (JSON и XML реализованы по-умолчанию); * Настройка формата ответа (JSON и XML реализованы по умолчанию);
* Получение сериализованных объектов с нужной вам выборкой полей; * Получение сериализованных объектов с нужной вам выборкой полей;
* Надлежащее форматирование данных и ошибок при их валидации; * Надлежащее форматирование данных и ошибок при их валидации;
* Поддержка [HATEOAS](http://en.wikipedia.org/wiki/HATEOAS); * Поддержка [HATEOAS](http://en.wikipedia.org/wiki/HATEOAS);
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
Вы можете использовать два столбца в таблице user для хранения количества разрешённых запросов и времени последней проверки. Вы можете использовать два столбца в таблице user для хранения количества разрешённых запросов и времени последней проверки.
В методах `loadAllowance()` и `saveAllowance()` можно реализовать чтение и сохранение значений этих столбцов в соответствии В методах `loadAllowance()` и `saveAllowance()` можно реализовать чтение и сохранение значений этих столбцов в соответствии
с данными текущего аутентифицированного пользователя. Для улучшения производительности можно попробовать хранить эту с данными текущего аутентифицированного пользователя. Для улучшения производительности можно попробовать хранить эту
информацию в кеше или NoSQL хранилище. информацию в кэше или NoSQL хранилище.
Как только соответствующий интерфейс будет реализован в классе identity, Yii начнёт автоматически проверять ограничения Как только соответствующий интерфейс будет реализован в классе identity, Yii начнёт автоматически проверять ограничения
частоты запросов при помощи [[yii\filters\RateLimiter]], фильтра действий для [[yii\rest\Controller]]. При превышении частоты запросов при помощи [[yii\filters\RateLimiter]], фильтра действий для [[yii\rest\Controller]]. При превышении
......
...@@ -26,7 +26,7 @@ RESTful API строятся вокруг доступа к *ресурсам* ...@@ -26,7 +26,7 @@ RESTful API строятся вокруг доступа к *ресурсам*
Вы можете указать какие данные включать в представление ресурса в виде массива путём переопределения методов Вы можете указать какие данные включать в представление ресурса в виде массива путём переопределения методов
[[yii\base\Model::fields()|fields()]] и/или [[yii\base\Model::extraFields()|extraFields()]]. Разница между ними в том, [[yii\base\Model::fields()|fields()]] и/или [[yii\base\Model::extraFields()|extraFields()]]. Разница между ними в том,
что первый определяет набор полей которые всегда будут включены в массив, а второй определяет дополнительные поля, которые что первый определяет набор полей, которые всегда будут включены в массив, а второй определяет дополнительные поля, которые
пользователь может запросить через параметр `expand`: пользователь может запросить через параметр `expand`:
``` ```
......
...@@ -85,7 +85,7 @@ Url::previous(); // получить ранее сохраненный URL ...@@ -85,7 +85,7 @@ Url::previous(); // получить ранее сохраненный URL
>**Совет**: чтобы сгенерировать URL с хэштэгом, например `/index.php?r=site/page&id=100#title`, укажите параметр `#` в хелпере таким образом: >**Совет**: чтобы сгенерировать URL с хэштэгом, например `/index.php?r=site/page&id=100#title`, укажите параметр `#` в хелпере таким образом:
`Url::to(['post/read', 'id' => 100, '#' => 'title'])`. `Url::to(['post/read', 'id' => 100, '#' => 'title'])`.
Также существует метод `Url::canonical()` , который позволяет создать [канонический URL](https://en.wikipedia.org/wiki/Canonical_link_element) (статья на англ., перевода пока нет) для текущего действия. Этот метод при создании игнорирует все параметры действия кроме тех, которые были переданы как аргументы. Также существует метод `Url::canonical()`, который позволяет создать [канонический URL](https://en.wikipedia.org/wiki/Canonical_link_element) (статья на англ., перевода пока нет) для текущего действия. Этот метод при создании игнорирует все параметры действия кроме тех, которые были переданы как аргументы.
Пример: Пример:
```php ```php
......
...@@ -34,7 +34,7 @@ basic/ корневой каталог приложения ...@@ -34,7 +34,7 @@ basic/ корневой каталог приложения
commands/ содержит классы консольных команд commands/ содержит классы консольных команд
controllers/ контроллеры controllers/ контроллеры
models/ модели models/ модели
runtime/ файлы, которые генерирует Yii во время выполнения приложения (логи, кеш и т.п.) runtime/ файлы, которые генерирует Yii во время выполнения приложения (логи, кэш и т.п.)
vendor/ содержит пакеты Composer'а и, собственно, сам фреймворк Yii vendor/ содержит пакеты Composer'а и, собственно, сам фреймворк Yii
views/ виды приложения views/ виды приложения
web/ корневая директория Web приложения. Содержит файлы, доступные через Web web/ корневая директория Web приложения. Содержит файлы, доступные через Web
......
...@@ -50,14 +50,14 @@ ...@@ -50,14 +50,14 @@
## Встроенные компоненты приложения <a name="core-application-components"></a> ## Встроенные компоненты приложения <a name="core-application-components"></a>
В Yii есть несколько *встроенных* компонентов приложения, с фиксированными ID и конфигурациями по-умолчанию. Например, В Yii есть несколько *встроенных* компонентов приложения, с фиксированными ID и конфигурациями по умолчанию. Например,
компонент [[yii\web\Application::request|request]] используется для сбора информации о запросе пользователя и разбора его в компонент [[yii\web\Application::request|request]] используется для сбора информации о запросе пользователя и разбора его в
определенный [маршрут](runtime-routing.md); компонент [[yii\base\Application::db|db]] представляет собой соединение с базой данных, определенный [маршрут](runtime-routing.md); компонент [[yii\base\Application::db|db]] представляет собой соединение с базой данных,
через которое вы можете выполнять запросы. Именно с помощью этих встроенных компонентов Yii приложения могут обработать через которое вы можете выполнять запросы. Именно с помощью этих встроенных компонентов Yii приложения могут обработать
запрос пользователя. запрос пользователя.
Ниже представлен список встроенных компонентов приложения. Вы можете конфигурировать их также как и другие компоненты приложения. Ниже представлен список встроенных компонентов приложения. Вы можете конфигурировать их также как и другие компоненты приложения.
Когда вы конфигурируете встроенный компонент приложения и не указываете класс этого компонента, то значение по-умолчанию будет использовано. Когда вы конфигурируете встроенный компонент приложения и не указываете класс этого компонента, то значение по умолчанию будет использовано.
* [[yii\web\AssetManager|assetManager]]: используется для управления и опубликования ресурсов приложения. * [[yii\web\AssetManager|assetManager]]: используется для управления и опубликования ресурсов приложения.
Более детальная информация представлена в разделе [Ресурсы](output-assets.md); Более детальная информация представлена в разделе [Ресурсы](output-assets.md);
......
...@@ -225,7 +225,7 @@ ID `post` будет соответствовать `app\controllers\PostControl ...@@ -225,7 +225,7 @@ ID `post` будет соответствовать `app\controllers\PostControl
#### [[yii\base\Application::controllerNamespace|controllerNamespace]] <a name="controllerNamespace"></a> #### [[yii\base\Application::controllerNamespace|controllerNamespace]] <a name="controllerNamespace"></a>
Данное свойство указывает пространство имен, в котором по-умолчанию должны находится названия классов контроллеров. Данное свойство указывает пространство имен, в котором по умолчанию должны находится названия классов контроллеров.
По-умолчанию значение равно `app\controllers`. Если ID контроллера `post`, то согласно соглашению, соответствующий класс По-умолчанию значение равно `app\controllers`. Если ID контроллера `post`, то согласно соглашению, соответствующий класс
контроллера (без пространства имен) будет равен `PostController`, а полное название класса будет равно `app\controllers\PostController`. контроллера (без пространства имен) будет равен `PostController`, а полное название класса будет равно `app\controllers\PostController`.
...@@ -247,7 +247,7 @@ ID `post` будет соответствовать `app\controllers\PostControl ...@@ -247,7 +247,7 @@ ID `post` будет соответствовать `app\controllers\PostControl
Значение данного свойства определяется различными аспектами [интернационализации](tutorial-i18n.md), в том числе Значение данного свойства определяется различными аспектами [интернационализации](tutorial-i18n.md), в том числе
переводом сообщений, форматированием дат, форматированием чисел, и т. д. Например, виджет [[yii\jui\DatePicker]] переводом сообщений, форматированием дат, форматированием чисел, и т. д. Например, виджет [[yii\jui\DatePicker]]
использует данное свойство для определения по-умолчанию языка, на котором должен быть отображен календарь и формат данных использует данное свойство для определения по умолчанию языка, на котором должен быть отображен календарь и формат данных
для календаря. для календаря.
Рекомендуется что вы будете указывать язык в рамках стандарта [IETF](http://en.wikipedia.org/wiki/IETF_language_tag). Рекомендуется что вы будете указывать язык в рамках стандарта [IETF](http://en.wikipedia.org/wiki/IETF_language_tag).
...@@ -348,7 +348,7 @@ $width = \Yii::$app->params['thumbnail.size'][0]; ...@@ -348,7 +348,7 @@ $width = \Yii::$app->params['thumbnail.size'][0];
### Полезные свойства <a name="useful-properties"></a> ### Полезные свойства <a name="useful-properties"></a>
Свойства, указанные в данном подразделе, не являются часто конфигурируемыми, т. к. их значения по-умолчанию Свойства, указанные в данном подразделе, не являются часто конфигурируемыми, т. к. их значения по умолчанию
соответствуют общепринятым соглашениям. Однако, вы можете их настроить, если вам нужно использовать другие соответствуют общепринятым соглашениям. Однако, вы можете их настроить, если вам нужно использовать другие
соглашения. соглашения.
...@@ -364,14 +364,14 @@ $width = \Yii::$app->params['thumbnail.size'][0]; ...@@ -364,14 +364,14 @@ $width = \Yii::$app->params['thumbnail.size'][0];
Свойство указывает [маршрут](runtime-routing.md), который должно использовать приложение, когда он не указан Свойство указывает [маршрут](runtime-routing.md), который должно использовать приложение, когда он не указан
во входящем запросе. Маршрут может состоять из ID модуля, ID контроллера и/или ID действия. Например, `help`, во входящем запросе. Маршрут может состоять из ID модуля, ID контроллера и/или ID действия. Например, `help`,
`post/create`, `admin/post/create`. Если действие не указано, то будет использовано значение по-умолчанию `post/create`, `admin/post/create`. Если действие не указано, то будет использовано значение по умолчанию
указанное в [[yii\base\Controller::defaultAction]]. указанное в [[yii\base\Controller::defaultAction]].
Для [yii\web\Application|веб приложений], значение по-умолчанию для данного свойства равно `'site'`, что означает Для [yii\web\Application|веб приложений], значение по умолчанию для данного свойства равно `'site'`, что означает
контроллер `SiteController` и его действие по-умолчанию должно быть использовано. Таким образом, если вы попытаетесь контроллер `SiteController` и его действие по умолчанию должно быть использовано. Таким образом, если вы попытаетесь
получить доступ к приложению не указав маршрут, оно покажет вам результат действия `app\controllers\SiteController::actionIndex()`. получить доступ к приложению не указав маршрут, оно покажет вам результат действия `app\controllers\SiteController::actionIndex()`.
Для [yii\console\Application|консольных приложений], значение по-умолчанию равно `'help'`, означающее, что встроенная Для [yii\console\Application|консольных приложений], значение по умолчанию равно `'help'`, означающее, что встроенная
команда [[yii\console\controllers\HelpController::actionIndex()]] должна быть использована. Таким образом, если вы команда [[yii\console\controllers\HelpController::actionIndex()]] должна быть использована. Таким образом, если вы
выполните команду `yii` без аргументов, вам будет отображена справочная информация. выполните команду `yii` без аргументов, вам будет отображена справочная информация.
...@@ -412,19 +412,19 @@ $width = \Yii::$app->params['thumbnail.size'][0]; ...@@ -412,19 +412,19 @@ $width = \Yii::$app->params['thumbnail.size'][0];
#### [[yii\base\Application::layout|layout]] <a name="layout"></a> #### [[yii\base\Application::layout|layout]] <a name="layout"></a>
Данное свойство указывает имя шаблона по-умолчанию, который должен быть использовать при формировании [представлений](structure-views.md). Данное свойство указывает имя шаблона по умолчанию, который должен быть использовать при формировании [представлений](structure-views.md).
Значение по-умолчанию равно `'main'`, означающее, что должен быть использован шаблон `main.php` в [папке шаблонов](#layoutPath). Значение по умолчанию равно `'main'`, означающее, что должен быть использован шаблон `main.php` в [папке шаблонов](#layoutPath).
Если оба свойства [папка шаблонов](#layoutPath) и [папка представлений](#viewPath) имеют значение по-умолчаниею, Если оба свойства [папка шаблонов](#layoutPath) и [папка представлений](#viewPath) имеют значение по умолчанию,
то файл шаблона по-умолчанию может быть представлен псевдонимом пути как `@app/views/layouts/main.php`. то файл шаблона по умолчанию может быть представлен псевдонимом пути как `@app/views/layouts/main.php`.
Для отключения использования шаблона, вы можете указать данное свойство как `false`, хотя это используется очень редко. Для отключения использования шаблона, вы можете указать данное свойство как `false`, хотя это используется очень редко.
#### [[yii\base\Application::layoutPath|layoutPath]] <a name="layoutPath"></a> #### [[yii\base\Application::layoutPath|layoutPath]] <a name="layoutPath"></a>
Свойство указывает путь, по которому следует искать шаблоны. Значение по-умолчанию равно `layouts`, означающее подпапку Свойство указывает путь, по которому следует искать шаблоны. Значение по умолчанию равно `layouts`, означающее подпапку
в [папке представлений](#viewPath). Если значение [папки представлений](#viewPath) является значением по-умолчанию, то в [папке представлений](#viewPath). Если значение [папки представлений](#viewPath) является значением по умолчанию, то
папка шаблонов по-умолчанию может быть представлена псевдонимом пути как `@app/views/layouts`. папка шаблонов по умолчанию может быть представлена псевдонимом пути как `@app/views/layouts`.
Вы можете настроить данное свойство как папку так и как [псевдоним](concept-aliases.md). Вы можете настроить данное свойство как папку так и как [псевдоним](concept-aliases.md).
...@@ -443,14 +443,14 @@ $width = \Yii::$app->params['thumbnail.size'][0]; ...@@ -443,14 +443,14 @@ $width = \Yii::$app->params['thumbnail.size'][0];
#### [[yii\base\Application::viewPath|viewPath]] <a name="viewPath"></a> #### [[yii\base\Application::viewPath|viewPath]] <a name="viewPath"></a>
Данное свойство указывает базовую папку,где содержаться все файлы представлений. Значение по-умолчанию представляет Данное свойство указывает базовую папку,где содержаться все файлы представлений. Значение по умолчанию представляет
собой псевдоним `@app/views`. Вы можете настроить данное свойство как папку так и как [псевдоним](concept-aliases.md). собой псевдоним `@app/views`. Вы можете настроить данное свойство как папку так и как [псевдоним](concept-aliases.md).
#### [[yii\base\Application::vendorPath|vendorPath]] <a name="vendorPath"></a> #### [[yii\base\Application::vendorPath|vendorPath]] <a name="vendorPath"></a>
Свойство указывает папку сторонних библиотек, которые используются и управляются [Composer](http://getcomposer.org). Свойство указывает папку сторонних библиотек, которые используются и управляются [Composer](http://getcomposer.org).
Она содержит все сторонние библиотеки используемые приложением, включая Yii фреймворк. Значение по-умолчанию Она содержит все сторонние библиотеки используемые приложением, включая Yii фреймворк. Значение по умолчанию
представляет собой псевдоним `@app/vendor`. представляет собой псевдоним `@app/vendor`.
Вы можете настроить данное свойство как папку так и как [псевдоним](concept-aliases.md). При изменении данного свойства, Вы можете настроить данное свойство как папку так и как [псевдоним](concept-aliases.md). При изменении данного свойства,
...@@ -462,7 +462,7 @@ $width = \Yii::$app->params['thumbnail.size'][0]; ...@@ -462,7 +462,7 @@ $width = \Yii::$app->params['thumbnail.size'][0];
#### [[yii\console\Application::enableCoreCommands|enableCoreCommands]] <a name="enableCoreCommands"></a> #### [[yii\console\Application::enableCoreCommands|enableCoreCommands]] <a name="enableCoreCommands"></a>
Данное свойство поддерживается только [[yii\console\Application|консольными приложениями]]. Оно указывает Данное свойство поддерживается только [[yii\console\Application|консольными приложениями]]. Оно указывает
нужно ли использовать встроенные в Yii консольные команды. Значение по-умолчанию равно `true`. нужно ли использовать встроенные в Yii консольные команды. Значение по умолчанию равно `true`.
## События приложения <a name="application-events"></a> ## События приложения <a name="application-events"></a>
......
...@@ -130,7 +130,7 @@ ID контроллеров также могут содержать префи ...@@ -130,7 +130,7 @@ ID контроллеров также могут содержать префи
* Добавить в начало [[yii\base\Application::controllerNamespace|пространство имен контроллеров]]. * Добавить в начало [[yii\base\Application::controllerNamespace|пространство имен контроллеров]].
Ниже приведены несколько примеров, с учетом того, что [[yii\base\Application::controllerNamespace|пространство имен контроллеров]] Ниже приведены несколько примеров, с учетом того, что [[yii\base\Application::controllerNamespace|пространство имен контроллеров]]
имеет значение по-умолчанию равное `app\controllers`: имеет значение по умолчанию равное `app\controllers`:
* `article` соответствует `app\controllers\ArticleController`; * `article` соответствует `app\controllers\ArticleController`;
* `post-comment` соответствует `app\controllers\PostCommentController`; * `post-comment` соответствует `app\controllers\PostCommentController`;
...@@ -172,14 +172,14 @@ ID контроллеров также могут содержать префи ...@@ -172,14 +172,14 @@ ID контроллеров также могут содержать префи
] ]
``` ```
### Контроллер по-умолчанию <a name="default-controller"></a> ### Контроллер по умолчанию <a name="default-controller"></a>
Каждое приложение имеет контроллер по-умолчанию, указанный через свойство [[yii\base\Application::defaultRoute]]. Каждое приложение имеет контроллер по умолчанию, указанный через свойство [[yii\base\Application::defaultRoute]].
Когда в запросе не указан [маршрут](#ids-routes), тогда будет использован маршрут указанный в данном свойстве. Когда в запросе не указан [маршрут](#ids-routes), тогда будет использован маршрут указанный в данном свойстве.
Для [[yii\web\Application|Веб приложений]], это значение `'site'`, в то время как для [[yii\console\Application|консольных приложений]], Для [[yii\web\Application|Веб приложений]], это значение `'site'`, в то время как для [[yii\console\Application|консольных приложений]],
это `'help'`. Таким образом, если задан URL `http://hostname/index.php`, это означает, что контроллер `site` выполнит обработку запроса. это `'help'`. Таким образом, если задан URL `http://hostname/index.php`, это означает, что контроллер `site` выполнит обработку запроса.
Вы можете изменить контроллер по-умолчанию следующим образом в [настройках приложения](structure-applications.md#application-configurations): Вы можете изменить контроллер по умолчанию следующим образом в [настройках приложения](structure-applications.md#application-configurations):
```php ```php
[ [
...@@ -375,10 +375,10 @@ public function actionView(array $id, $version = null) ...@@ -375,10 +375,10 @@ public function actionView(array $id, $version = null)
о параметрах консольных приложений представлено в секции [Консольные команды](tutorial-console.md). о параметрах консольных приложений представлено в секции [Консольные команды](tutorial-console.md).
### Действие по-умолчанию <a name="default-action"></a> ### Действие по умолчанию <a name="default-action"></a>
Каждый контроллер имеет действие, указанное через свойство [[yii\base\Controller::defaultAction]]. Каждый контроллер имеет действие, указанное через свойство [[yii\base\Controller::defaultAction]].
Когда [маршрут](#ids-routes) содержит только ID контроллера, то подразумевается, что действие контроллера по-умолчанию Когда [маршрут](#ids-routes) содержит только ID контроллера, то подразумевается, что действие контроллера по умолчанию
было запрошено. было запрошено.
По-умолчанию, это действие имеет значение `index`. Если вы хотите изменить это значение, просто переопределите данное По-умолчанию, это действие имеет значение `index`. Если вы хотите изменить это значение, просто переопределите данное
...@@ -409,7 +409,7 @@ class SiteController extends Controller ...@@ -409,7 +409,7 @@ class SiteController extends Controller
1. Метод [[yii\base\Controller::init()]] будет вызван после того как контроллер будет создан и сконфигурирован; 1. Метод [[yii\base\Controller::init()]] будет вызван после того как контроллер будет создан и сконфигурирован;
2. Контроллер создает объект действия, основываясь на запрошенном ID действия: 2. Контроллер создает объект действия, основываясь на запрошенном ID действия:
* Если ID действия не указан, то будет использовано [[yii\base\Controller::defaultAction|ID действия по-умолчанию]]; * Если ID действия не указан, то будет использовано [[yii\base\Controller::defaultAction|ID действия по умолчанию]];
* Если ID действия найдено в [[yii\base\Controller::actions()|карте действий]], то отдельное действие будет создано; * Если ID действия найдено в [[yii\base\Controller::actions()|карте действий]], то отдельное действие будет создано;
* Если ID действия соответствует методу действия, то встроенное действие будет создано; * Если ID действия соответствует методу действия, то встроенное действие будет создано;
* В противном случае, будет выброшено исключение [[yii\base\InvalidRouteException]]. * В противном случае, будет выброшено исключение [[yii\base\InvalidRouteException]].
......
...@@ -239,7 +239,7 @@ ID контроллера: <?= $this->context->id ?> ...@@ -239,7 +239,7 @@ ID контроллера: <?= $this->context->id ?>
### Передача данных между видами <a name="sharing-data-among-views"></a> ### Передача данных между видами <a name="sharing-data-among-views"></a>
[[yii\base\View|Компонент вида]] имеет свойство [[yii\base\View::params|params]] , которое вы можете использовать для обмена данными между видами. [[yii\base\View|Компонент вида]] имеет свойство [[yii\base\View::params|params]], которое вы можете использовать для обмена данными между видами.
Например, в виде `about` вы можете указать текущий сегмент хлебных крошек с помощью следующего кода. Например, в виде `about` вы можете указать текущий сегмент хлебных крошек с помощью следующего кода.
...@@ -298,7 +298,7 @@ use yii\helpers\Html; ...@@ -298,7 +298,7 @@ use yii\helpers\Html;
Большинство шаблонов вызывают методы, аналогично тому, как это сделано в примере выше, чтобы скрипты и тэги, зарегистированные в других местах приложения могли быть правильно отображены в местах вызова (например, в шаблоне). Большинство шаблонов вызывают методы, аналогично тому, как это сделано в примере выше, чтобы скрипты и тэги, зарегистированные в других местах приложения могли быть правильно отображены в местах вызова (например, в шаблоне).
- [[yii\base\View::beginPage()|beginPage()]]: Этот метод нужно вызывать в самом начале шаблона. - [[yii\base\View::beginPage()|beginPage()]]: Этот метод нужно вызывать в самом начале шаблона.
Он вызывает событие [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]] , которое происходит при начале обработки страницы. Он вызывает событие [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]], которое происходит при начале обработки страницы.
- [[yii\base\View::endPage()|endPage()]]: Этот метод нужно вызывать в конце страницы. - [[yii\base\View::endPage()|endPage()]]: Этот метод нужно вызывать в конце страницы.
Он вызывает событие [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]] . Оно указывает на обработку конца страницы. Он вызывает событие [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]] . Оно указывает на обработку конца страницы.
- [[yii\web\View::head()|head()]]: Этот метод нужно вызывать в `<head>` секции страницы html. - [[yii\web\View::head()|head()]]: Этот метод нужно вызывать в `<head>` секции страницы html.
...@@ -320,7 +320,7 @@ use yii\helpers\Html; ...@@ -320,7 +320,7 @@ use yii\helpers\Html;
### Использование шаблонов <a name="using-layouts"></a> ### Использование шаблонов <a name="using-layouts"></a>
Как было описано в секции [Рендеринг в контроллерах](#rendering-in-controllers) , когда вы рендерите вид, вызывая метод [[yii\base\Controller::render()|render()]] из контроллера, к результату рендеринга будет применен шаблон. По умолчанию будет использован шаблон `@app/views/layouts/main.php` . Как было описано в секции [Рендеринг в контроллерах](#rendering-in-controllers), когда вы рендерите вид, вызывая метод [[yii\base\Controller::render()|render()]] из контроллера, к результату рендеринга будет применен шаблон. По умолчанию будет использован шаблон `@app/views/layouts/main.php` .
Вы можете использовать разные шаблоны, конфигурируя [[yii\base\Application::layout]] или [[yii\base\Controller::layout]]. Вы можете использовать разные шаблоны, конфигурируя [[yii\base\Application::layout]] или [[yii\base\Controller::layout]].
Первый переопределяет шаблон, который используется по умолчанию всеми контроллерами, а второй переопределяет шаблон в отдельном контроллере. Первый переопределяет шаблон, который используется по умолчанию всеми контроллерами, а второй переопределяет шаблон в отдельном контроллере.
...@@ -391,7 +391,7 @@ Yii определяет какой шаблон использовать для ...@@ -391,7 +391,7 @@ Yii определяет какой шаблон использовать для
Например, вы определяете (записываете) блок в виде и отображаете его в шаблоне. Например, вы определяете (записываете) блок в виде и отображаете его в шаблоне.
Для определения блока вызываются методы [[yii\base\View::beginBlock()|beginBlock()]] и [[yii\base\View::endBlock()|endBlock()]]. Для определения блока вызываются методы [[yii\base\View::beginBlock()|beginBlock()]] и [[yii\base\View::endBlock()|endBlock()]].
После определения, блок доступен через `$view->blocks[$blockID]` , где `$blockID` - это уникальный ID, который вы присваиваете блоку После определения, блок доступен через `$view->blocks[$blockID]`, где `$blockID` - это уникальный ID, который вы присваиваете блоку
в начале определения. в начале определения.
В примере ниже показано, как можно использовать блоки, определенные в виде, чтобы динамически изменять фрагменты шаблона. В примере ниже показано, как можно использовать блоки, определенные в виде, чтобы динамически изменять фрагменты шаблона.
......
...@@ -108,7 +108,7 @@ class HelloWidget extends Widget ...@@ -108,7 +108,7 @@ class HelloWidget extends Widget
} }
``` ```
Для того, что бы использовать этот виджет, достаточно добавить в представление следующий код: Для того, чтобы использовать этот виджет, достаточно добавить в представление следующий код:
```php ```php
<?php <?php
...@@ -177,7 +177,7 @@ public function run() ...@@ -177,7 +177,7 @@ public function run()
По умолчанию, файлы представлений виджетов должны находиться в директории `WidgetPath/views`, где `WidgetPath` - По умолчанию, файлы представлений виджетов должны находиться в директории `WidgetPath/views`, где `WidgetPath` -
директория, содержащая файл класса виджета. Таким образом, в приведенном выше примере, для виджета будет директория, содержащая файл класса виджета. Таким образом, в приведенном выше примере, для виджета будет
использован файл представления `@app/components/views/hello.php`, при этом файл с классом виджета расположен в использован файл представления `@app/components/views/hello.php`, при этом файл с классом виджета расположен в
`@app/components`. Для того, что бы изменить директорию, в которой содержатся файлы-представления для виджета, `@app/components`. Для того, чтобы изменить директорию, в которой содержатся файлы-представления для виджета,
следует переопределить метод [[yii\base\Widget::getViewPath()]]. следует переопределить метод [[yii\base\Widget::getViewPath()]].
......
...@@ -238,7 +238,7 @@ function foo($model, $attribute) { ...@@ -238,7 +238,7 @@ function foo($model, $attribute) {
строка, содержащая имена файловых расширений, разделенных пробелом или запятой (пр.: "gif, jpg"). строка, содержащая имена файловых расширений, разделенных пробелом или запятой (пр.: "gif, jpg").
Имя расширения не чувствительно к регистру. По умолчанию - null, что значит, что все имена файловых расширений Имя расширения не чувствительно к регистру. По умолчанию - null, что значит, что все имена файловых расширений
допустимы. допустимы.
- `mimeTypes`: список MIME-типов которые допустимы для загрузки. Это может быть или массив, или строка, - `mimeTypes`: список MIME-типов, которые допустимы для загрузки. Это может быть или массив, или строка,
содержащая MIME-типы файлов, разделенные пробелом или запятой (пример: "image/jpeg, image/png"). содержащая MIME-типы файлов, разделенные пробелом или запятой (пример: "image/jpeg, image/png").
Имена mime-типов не чувствительны к регистру. По умолчанию - null, что значит, что допустимы все MIME-типы. Имена mime-типов не чувствительны к регистру. По умолчанию - null, что значит, что допустимы все MIME-типы.
- `minSize`: минимальный размер файла в байтах, разрешенный для загрузки. По умолчанию - null, что значит, что нет - `minSize`: минимальный размер файла в байтах, разрешенный для загрузки. По умолчанию - null, что значит, что нет
......
...@@ -389,7 +389,6 @@ $width = \Yii::$app->params['thumbnail.size'][0]; ...@@ -389,7 +389,6 @@ $width = \Yii::$app->params['thumbnail.size'][0];
如果 [视图路径](#viewPath) 使用默认值,默认的布局路径别名为`@app/views/layouts`。 如果 [视图路径](#viewPath) 使用默认值,默认的布局路径别名为`@app/views/layouts`。
该属性需要配置成一个目录或 路径 [别名](concept-aliases.md)。 该属性需要配置成一个目录或 路径 [别名](concept-aliases.md)。
You may configure it as a directory or a path [alias](concept-aliases.md).
#### [[yii\base\Application::runtimePath|runtimePath]] <a name="runtimePath"></a> #### [[yii\base\Application::runtimePath|runtimePath]] <a name="runtimePath"></a>
......
...@@ -283,7 +283,7 @@ class HelloWorldAction extends Action ...@@ -283,7 +283,7 @@ class HelloWorldAction extends Action
### 操作结果 <a name="action-results"></a> ### 操作结果 <a name="action-results"></a>
操作方法或独立操作的`run()`方法的返回值非常中药,它表示对应操作结果。 操作方法或独立操作的`run()`方法的返回值非常重要,它表示对应操作结果。
返回值可为 [响应](runtime-responses.md) 对象,作为响应发送给终端用户。 返回值可为 [响应](runtime-responses.md) 对象,作为响应发送给终端用户。
...@@ -378,8 +378,7 @@ class SiteController extends Controller ...@@ -378,8 +378,7 @@ class SiteController extends Controller
## 控制器生命周期 <a name="controller-lifecycle"></a> ## 控制器生命周期 <a name="controller-lifecycle"></a>
处理一个请求时,[应用主体](structure-applications.md) 会根据请求[路由](#routes)创建一个控制器,will create a controller 处理一个请求时,[应用主体](structure-applications.md) 会根据请求[路由](#routes)创建一个控制器,控制器经过以下生命周期来完成请求:
控制器经过以下生命周期来完成请求:
1. 在控制器创建和配置后,[[yii\base\Controller::init()]] 方法会被调用。 1. 在控制器创建和配置后,[[yii\base\Controller::init()]] 方法会被调用。
2. 控制器根据请求操作ID创建一个操作对象: 2. 控制器根据请求操作ID创建一个操作对象:
......
...@@ -113,7 +113,7 @@ echo Yii::$app->formatter->asDate('now', 'php:Y-m-d'); // 2014-10-06 ...@@ -113,7 +113,7 @@ echo Yii::$app->formatter->asDate('now', 'php:Y-m-d'); // 2014-10-06
### Time zones <a name="time-zones"></a> ### Time zones <a name="time-zones"></a>
When formatting date and time values, Yii will convert them to the [[yii\i18n\Formatter::timeZone|configured time zone]]. When formatting date and time values, Yii will convert them to the [[yii\i18n\Formatter::timeZone|configured time zone]].
Therefor the input value is assumed to be in UTC unless a time zone is explicitly given. For this reason Therefore the input value is assumed to be in UTC unless a time zone is explicitly given. For this reason
it is recommended to store all date and time values in UTC preferably as a UNIX timestamp, which is always UTC by definition. it is recommended to store all date and time values in UTC preferably as a UNIX timestamp, which is always UTC by definition.
If the input value is in a time zone different from UTC, the time zone has to be stated explicitly like in the following example: If the input value is in a time zone different from UTC, the time zone has to be stated explicitly like in the following example:
......
...@@ -6,7 +6,7 @@ be used. Therefore, each request should come with some sort of authentication cr ...@@ -6,7 +6,7 @@ be used. Therefore, each request should come with some sort of authentication cr
the user authentication status may not be maintained by sessions or cookies. A common practice is the user authentication status may not be maintained by sessions or cookies. A common practice is
to send a secret access token with each request to authenticate the user. Since an access token to send a secret access token with each request to authenticate the user. Since an access token
can be used to uniquely identify and authenticate a user, **API requests should always be sent can be used to uniquely identify and authenticate a user, **API requests should always be sent
via HTTPS to prevent from man-in-the-middle (MitM) attacks**. via HTTPS to prevent man-in-the-middle (MitM) attacks**.
There are different ways to send an access token: There are different ways to send an access token:
......
...@@ -71,8 +71,8 @@ public function fields() ...@@ -71,8 +71,8 @@ public function fields()
// field name is "email", the corresponding attribute name is "email_address" // field name is "email", the corresponding attribute name is "email_address"
'email' => 'email_address', 'email' => 'email_address',
// field name is "name", its value is defined by a PHP callback // field name is "name", its value is defined by a PHP callback
'name' => function () { 'name' => function ($model) {
return $this->first_name . ' ' . $this->last_name; return $model->first_name . ' ' . $model->last_name;
}, },
]; ];
} }
......
...@@ -493,7 +493,7 @@ In summary, models ...@@ -493,7 +493,7 @@ In summary, models
You may usually consider the last recommendation above when you are developing large complex systems. You may usually consider the last recommendation above when you are developing large complex systems.
In these systems, models could be very fat because they are used in many places and may thus contain many sets In these systems, models could be very fat because they are used in many places and may thus contain many sets
of rules and business logic. This often ends up in a nightmare in maintaining the model code of rules and business logic. This often ends up in a nightmare in maintaining the model code
because a single touch of the code could affect several different places. To make the mode code more maintainable, because a single touch of the code could affect several different places. To make the model code more maintainable,
you may take the following strategy: you may take the following strategy:
* Define a set of base model classes that are shared by different [applications](structure-applications.md) or * Define a set of base model classes that are shared by different [applications](structure-applications.md) or
......
...@@ -42,7 +42,7 @@ and rendering this view template. ...@@ -42,7 +42,7 @@ and rendering this view template.
Besides `$this`, there may be other predefined variables in a view, such as `$model` in the above Besides `$this`, there may be other predefined variables in a view, such as `$model` in the above
example. These variables represent the data that are *pushed* into the view by [controllers](structure-controllers.md) example. These variables represent the data that are *pushed* into the view by [controllers](structure-controllers.md)
or other objects whose trigger the [view rendering](#rendering-views). or other objects which trigger the [view rendering](#rendering-views).
> Tip: The predefined variables are listed in a comment block at beginning of a view so that they can > Tip: The predefined variables are listed in a comment block at beginning of a view so that they can
be recognized by IDEs. It is also a good way of documenting your views. be recognized by IDEs. It is also a good way of documenting your views.
......
...@@ -52,8 +52,8 @@ interface Arrayable ...@@ -52,8 +52,8 @@ interface Arrayable
* 'email', * 'email',
* 'firstName' => 'first_name', * 'firstName' => 'first_name',
* 'lastName' => 'last_name', * 'lastName' => 'last_name',
* 'fullName' => function () { * 'fullName' => function ($model) {
* return $this->first_name . ' ' . $this->last_name; * return $model->first_name . ' ' . $model->last_name;
* }, * },
* ]; * ];
* ``` * ```
......
...@@ -841,8 +841,8 @@ class Model extends Component implements IteratorAggregate, ArrayAccess, Arrayab ...@@ -841,8 +841,8 @@ class Model extends Component implements IteratorAggregate, ArrayAccess, Arrayab
* 'email', * 'email',
* 'firstName' => 'first_name', * 'firstName' => 'first_name',
* 'lastName' => 'last_name', * 'lastName' => 'last_name',
* 'fullName' => function () { * 'fullName' => function ($model) {
* return $this->first_name . ' ' . $this->last_name; * return $model->first_name . ' ' . $model->last_name;
* }, * },
* ]; * ];
* ``` * ```
......
...@@ -408,7 +408,7 @@ abstract class BaseMigrateController extends Controller ...@@ -408,7 +408,7 @@ abstract class BaseMigrateController extends Controller
* ~~~ * ~~~
* *
* @param integer $limit the maximum number of new migrations to be displayed. * @param integer $limit the maximum number of new migrations to be displayed.
* If it is 0, all available new migrations will be displayed. * If it is `all`, all available new migrations will be displayed.
* @throws \yii\console\Exception if invalid limit value passed * @throws \yii\console\Exception if invalid limit value passed
*/ */
public function actionNew($limit = 10) public function actionNew($limit = 10)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment