docs/guide-ja updated [ci skip]

This commit is contained in:
Nobuo Kihara
2015-05-22 20:09:10 +09:00
parent a63fc2ff59
commit 611e349f21
2 changed files with 66 additions and 112 deletions

View File

@ -97,18 +97,23 @@ public function rules()
``` ```
このバリデータは、入力値が正しい書式の date、time、または datetime であるかどうかをチェックします。 このバリデータは、入力値が正しい書式の date、time、または datetime であるかどうかをチェックします。
オプションとして、入力値を UNIX タイムスタンプに変換して、[[yii\validators\DateValidator::timestampAttribute|timestampAttribute]] によって指定された属性に保存することも出来ます。 オプションとして、入力値を UNIX タイムスタンプ (または、その他、機械による読み取りが可能な形式) に変換して、[[yii\validators\DateValidator::timestampAttribute|timestampAttribute]] によって指定された属性に保存することも出来ます。
- `format`: 検証される値が従っているべき日付/時刻の書式。 - `format`: 検証される値が従っているべき日付/時刻の書式。
これには [ICU manual](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax) で記述されている日付/時刻のパターンを使うことが出来ます。 これには [ICU manual](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax) で記述されている日付/時刻のパターンを使うことが出来ます。
あるいは、PHP の `Datetime` クラスによって認識される書式に接頭辞 `php:` を付けた文字列でも構いません。 あるいは、PHP の `Datetime` クラスによって認識される書式に接頭辞 `php:` を付けた文字列でも構いません。
サポートされている書式については、<http://php.net/manual/ja/datetime.createfromformat.php> を参照してください。 サポートされている書式については、<http://php.net/manual/ja/datetime.createfromformat.php> を参照してください。
このプロパティが設定されていないときは、`Yii::$app->formatter->dateFormat` の値を取ります。 このプロパティが設定されていないときは、`Yii::$app->formatter->dateFormat` の値を取ります。
- `timestampAttribute`: このバリデータが、入力された日付/時刻から変換した UNIX タイムスタンプを代入することが出来る属性の名前。 - `timestampAttribute`: このバリデータが、入力された日付/時刻から変換した UNIX タイムスタンプを代入することが出来る属性の名前。
これは、検証される属性と同じ属性であってもかまいません。 これは、検証される属性と同じ属性であってもかまいません。
その場合は、元の値は検証実行後にタイムスタンプで上書きされます。 その場合は、元の値は検証実行後にタイムスタンプで上書きされます。
[DatePicker で日付の入力を扱う](widget-jui#datepicker-date-input) に使用例がありますので、参照してください。 [DatePicker で日付の入力を扱う](widget-jui#datepicker-date-input) に使用例がありますので、参照してください。
バージョン 2.0.4 以降では、[[yii\validators\DateValidator::$timestampAttributeFormat|$timestampAttributeFormat]] と [[yii\validators\DateValidator::$timestampAttributeTimeZone|$timestampAttributeTimeZone]] を使って、この属性に対するフォーマットとタイムゾーンを指定することが出来ます。
- バージョン 2.0.4 以降では、タイムスタンプの [[yii\validators\DateValidator::$min|最小値]] または [[yii\validators\DateValidator::$max|最大値]] を指定することも出来ます。
入力が必須でない場合には、date バリデータに加えて、default バリデータ (デフォルト値フィルタ) を追加すれば、空の入力値が `NULL` として保存されることを保証することが出来ます。 入力が必須でない場合には、date バリデータに加えて、default バリデータ (デフォルト値フィルタ) を追加すれば、空の入力値が `NULL` として保存されることを保証することが出来ます。
そうしないと、データベースに `0000-00-00` という日付が保存されたり、デートピッカーの入力フィールドが `1970-01-01` になったりしてしまいます。 そうしないと、データベースに `0000-00-00` という日付が保存されたり、デートピッカーの入力フィールドが `1970-01-01` になったりしてしまいます。

View File

@ -5,53 +5,58 @@
あなたのウェブアプリケーションのパフォーマンスは二つの部分に基づいています。 あなたのウェブアプリケーションのパフォーマンスは二つの部分に基づいています。
一つはフレームワークのパフォーマンスであり、もう一つはアプリケーションそのものです。 一つはフレームワークのパフォーマンスであり、もう一つはアプリケーションそのものです。
Yii は、そのままの状態でも、あなたのアプリケーションのパフォーマンスを劣化させる影響がかなり小さいものですが、本番環境のためには、さらに微調整することが可能です。 Yii は、そのままの状態でも、パフォーマンスを劣化させる影響がかなり小さいものですが、本番環境のためには、さらに微調整することが可能です。
アプリケーションに関しては、ベストプラクティスのいくつかを提供すると共に、それを Yii に適用する方法を例示します。 アプリケーションに関しては、ベストプラクティスのいくつかを提供すると共に、それを Yii に適用する方法を例示します。
環境を準備する ## PHP 環境を最適化する <span id="optimizing-php"></span>
--------------
PHP アプリケーションを走らせるための環境を正しく構成することは本当に重要です。 PHP 環境を正しく構成することは非常に重要です。
最大のパフォーマンスを得るためには、 最大のパフォーマンスを得るためには、
- 常に最新の安定した PHP バージョンを使うこと。 - 最新の安定した PHP バージョンを使うこと。
PHP は、メジャーリリースのたびに、顕著なパフォーマンスの改善とメモリ使用の削減がなされています。 使用する PHP メジャーリリースを上げると、顕著なパフォーマンスの改善がもたらされることがあります。
- PHP 5.4 以下には [APC](http://ru2.php.net/apc)、または、PHP 5.5 以上には [Opcache](http://php.net/opcache) を使うこと。 - [Opcache](http://php.net/opcache) (PHP 5.5 以降) または [APC](http://ru2.php.net/apc) (PHP 5.4 以前) を使って、バイトコードキャッシュを有効にすること。
このことは、非常に良いパフォーマンス強化をもたらします。 バイトコードキャッシュによって、リクエストが入ってくるたびに PHP スクリプトを解析してインクルードする時間の浪費を避けることが出来ます。
フレームワークを本番用に準備する ## デバッグモードを無効にする <span id="disable-debug"></span>
--------------------------------
### デバッグモードを無効化する 本番環境でアプリケーションを実行するときには、デバッグモードを無効にしなければなりません。
Yii は、`YII_DEBUG` という名前の定数の値を使って、デバッグモードを有効にすべきか否かを示します。
デバッグモードが有効になっているときは、Yii はデバッグ情報の生成と記録のために時間を余計に費やします。
アプリケーションを本番環境に配備する前に行うべき最初のことは、デバッグモード無効化です。 [エントリスクリプト](structure-entry-scripts.md) の冒頭に次のコード行を置くことによってデバッグモード無効にすることが出来ます。
Yii のアプリケーションは、`index.php` において定数 `YII_DEBUG``true` と定義されていると、デバッグモードで走ります。
従って、デバッグモードを無効にするために、以下のコードが `index.php` になければなりません。
```php ```php
defined('YII_DEBUG') or define('YII_DEBUG', false); defined('YII_DEBUG') or define('YII_DEBUG', false);
``` ```
デバッグモードは開発段階において非常に役に立ちますが、いくつかのコンポーネントがデバッグモードにおいて追加の負荷を発生させるため、パフォーマンスを劣化させます。 > Info|情報: `YII_DEBUG` のデフォルト値は false です。
例えば、メッセージロガーは、ログに記録されるすべてのメッセージについて、追加のデバッグ情報を記録します 従って、アプリケーションコードの他のどこかでこのデフォルト値を変更していないと確信できるなら、単に上記の行を削除してデバッグモードを無効にしても構いません。
### PHP opcode キャッシュを有効にする ## キャッシュのテクニックを使う <span id="using-caching"></span>
PHP opcode キャッシュを有効にすると、すべての PHP アプリケーションで、顕著にパフォーマンスが向上し、メモリ使用量が削減されます。 さまざまなキャッシュのテクニックを使うと、あなたのアプリケーションパフォーマンスを目に見えて改善することが出来ます。
Yii も例外ではありません たとえば、あなたのアプリケーションが Markdown 形式のテキスト入力をユーザに許可している場合、解析済みの Markdown のコンテントをキャッシュすることを考慮してください
Yii は [PHP 5.5 OPcache](http://php.net/manual/ja/book.opcache.php) と [APC PHP 拡張](http://php.net/manual/ja/book.apc.php) の両方でテストされています そうすれば、リクエストごとに毎回同じ Markdown テキストの解析を繰り返すことを回避できるでしょう
どちらのキャッシュも、PHP 中間コードを最適化して、入ってくるリクエストごとに PHP スクリプトを解析するために時間を消費することを回避します Yii によって提供されているキャッシュのサポートについて学ぶためには [キャッシュ](caching-overview.md) の節を参照してください
### ActiveRecord のデータベーススキーマキャッシュを有効にする ## スキーマキャッシュを有効にする <span id="enable-schema-caching"></span>
アプリケーションがアクティブレコードを使用している場合は、スキーマキャッシュを有効にして、データベーススキーマを解析するための時間を節約すべきです。 スキーマキャッシュは、[アクティブレコード](db-active-record.md) を使おうとする場合は、いつでも有効にすべき特別なキャッシュ機能です。
そうするためには、アプリケーションの構成情報 `config/web.php` において、`Connection::enableSchemaCache` プロパティを `true` に設定します。 ご存じのように、アクティブレコードは、賢いことに、あなたがわざわざ記述しなくても、DB テーブルに関するスキーマ情報 (カラムの名前、カラムのタイプ、外部キー制約など) を自動的に検出します。
アクティブレコードはこの情報を取得するために追加の SQL クエリを実行しています。
スキーマキャッシュを有効にすると、取得されたスキーマ情報はキャッシュに保存されて将来のクエリで再利用されるようになります。
スキーマキャッシュを有効にするためには、[アプリケーションの構成情報](concept-configurations.md) の中で、`cache` [アプリケーションコンポーネント](structure-application-components.md) にスキーマ情報を保存するように構成し、[[yii\db\Connection::enableSchemaCache]] を `true` に設定します。
```php ```php
return [ return [
// ... // ...
'components' => [ 'components' => [
// ... // ...
'cache' => [
'class' => 'yii\caching\FileCache',
],
'db' => [ 'db' => [
'class' => 'yii\db\Connection', 'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=mydatabase', 'dsn' => 'mysql:host=localhost;dbname=mydatabase',
@ -60,28 +65,23 @@ return [
'enableSchemaCache' => true, 'enableSchemaCache' => true,
// スキーマキャッシュの持続時間 // スキーマキャッシュの持続時間
// 'schemaCacheDuration' => 3600, 'schemaCacheDuration' => 3600,
// 使用されるキャッシュコンポーネントの名前。デフォルトは 'cache'。 // スキーマ情報を保存するのし使用されるキャッシュコンポーネントの名前
//'schemaCache' => 'cache', 'schemaCache' => 'cache',
],
'cache' => [
'class' => 'yii\caching\FileCache',
], ],
], ],
]; ];
``` ```
`cache` [アプリケーションコンポーネント](structure-application-components.md) が構成されていなければならないことに注意してください。 ## アセットを結合して最小化する <span id="optimizing-assets"></span>
### アセットを結合して最小化する 複雑なウェブページでは、多数の CSS や JavaScript のアセットファイルをインクルードすることがよくあります。
HTTP リクエストの回数、および、これらのアセットの全体としてのダウンロードサイズを削減するために、アセットを単一のファイルに結合して、それを圧縮することを考慮すべきです。
これによって、ページのロードにかかる時間とサーバの負荷を大きく削減することが出来ます。
詳細については、[アセット](structure-assets.md) の節を参照してください。
アセットは、典型的には JavaScript と CSS ですが、結合して圧縮することが出来ます。 ## セッションのためにより良いストレージを使用する
これにより、ページの読み込みにかかる時間をわずかながら削減して、アプリケーションのエンドユーザにより良いユーザ体験をもたらすことが出来ます。
これをどのようにすれば達成できるかについて学ぶためには、ガイドの [アセット](structure-assets.md) の節を参照してください。
### セッションのためにより良いストレージを使用する
デフォルトでは、PHP はセッションを処理するためにファイルを使います。 デフォルトでは、PHP はセッションを処理するためにファイルを使います。
開発と小さなプロジェクトではそれでも構いませんが、リクエストを並列処理するとなると、データベースのような別のストレージに変更する方が良いでしょう。 開発と小さなプロジェクトではそれでも構いませんが、リクエストを並列処理するとなると、データベースのような別のストレージに変更する方が良いでしょう。
@ -111,101 +111,50 @@ return [
サーバに [Redis](http://redis.io/) がある場合は、それをセッションのストレージに使用することを強く推奨します。 サーバに [Redis](http://redis.io/) がある場合は、それをセッションのストレージに使用することを強く推奨します。
アプリケーションを改善する
--------------------------
### サーバ側のキャッシュテクニックを使う ## データベースを最適化する <span id="optimizing-databases"></span>
キャッシュの節で説明されているように、Yii はウェブアプリケーションのパフォーマンスを著しく改善することが出来るキャッシュのソリューションをいくつか提供しています。 DB クエリの実行とデータベースからのデータ取得がウェブアプリケーションのパフォーマンスの主たるボトルネックになることがよくあります。
データの生成に長い時間を要するものがある場合は、データキャッシュの手法を使用して、データを生成する頻度を削減すること出来ま [データキャッシュ](caching-data.md) の使用によってパフォーマンスの劣化を緩和することは出来ますが、問題を完全に解決すること出来ません
ページのある部分が比較的静的なものであり続ける場合は、フラグメントキャッシュの手法を使用して、その部分のレンダリングの頻度を削減することが出来ます。
あるページ全体が比較的静的なものであり続ける場合は、ページキャッシュの手法を使用して、ページ全体のレンダリングのコストを節約することが出来ます。
### HTTP キャッシュを利用して、処理時間と帯域を節約する
HTTP キャッシュを利用すると、処理時間および帯域やリソースを著しく節約することが出来ます。
HTTP キャッシュは、`ETag` または `Last-Modified` ヘッダをアプリケーションのレスポンスで送信することによって実装することが出来ます。
ブラウザが HTTP の仕様に従って実装されていれば (ほとんどのブラウザがそうです)、コンテントは以前の状態と異なる場合にだけ取得されます。
正しいヘッダを作成することは手間のかかる仕事ですので、Yii は [[yii\filters\HttpCache]] というコントローラフィルタの形でショートカットを提供しています。
これを使うことはとても簡単です。
コントローラの中で `behaviors` メソッドを以下のように実装することが必要です。
```php
public function behaviors()
{
return [
'httpCache' => [
'class' => \yii\filters\HttpCache::className(),
'only' => ['list'],
'lastModified' => function ($action, $params) {
$q = new Query();
return strtotime($q->from('users')->max('updated_timestamp'));
},
// 'etagSeed' => function ($action, $params) {
// return // egat のシードをここで生成
//}
],
];
}
```
上記のコードでは、`etagSeed` または `lastModified` のどちらかを使うことが出来ます。
両方を実装する必要はありません。
目的は、コンテントを取得してレンダリングするよりも安価な方法を使って、コンテントが修正されたかどうかを判断することです。
`lastModified` はコンテントが最後に修正されたときの UNIX タイムスタンプを返さなければなりません。
一方 `etagSeed``ETag` ヘッダの値を生成するために使われる文字列を返さなければなりません。
### データベースの最適化
データベースからのデータ取得がウェブアプリケーションのパフォーマンスの主たるボトルネックになることがよくあります。
[キャッシュ](caching.md#Query-Caching) の使用によってパフォーマンスの劣化を緩和することは出来ますが、問題を完全に解決することは出来ません。
データベースが膨大なデータを抱えている場合、キャッシュされたデータが無効化されたときに最新のデータを取得するためのコストは、データベースとクエリが適切に設計されていないと、法外なものになり得ます。 データベースが膨大なデータを抱えている場合、キャッシュされたデータが無効化されたときに最新のデータを取得するためのコストは、データベースとクエリが適切に設計されていないと、法外なものになり得ます。
データベースのインデックスを上手に設計しましょう DB クエリのパフォーマンスを向上させるための一般的なテクニックは、フィルタの対象になるテーブルカラムにインデックスを作成することです
インデックスを付けると SELECT クエリを非常に速くすることが出来ます。ただし、INSERT、UPDATE、または DELTE のクエリは遅くなることがあります。 例えば、`username` によってユーザのレコードを検索する必要があるなら、`username` に対してインデックスを作成するべきです。
ただし、インデックスを付けると SELECT クエリを非常に速くすることが出来る代りに、INSERT、UPDATE、または DELTE のクエリが遅くなることに注意してください。
複雑なクエリに対しては、PHP コードの中からクエリを発行して DBMS にクエリを解析するように繰り返して求める代わりに、データベースビューを作成することを推奨します。
アクティブレコードを使い過ぎないでください。
アクティブレコード は OOP 流にデータをモデリングするには便利ですが、クエリ結果の各行を表すために一つまたは複数のオブジェクトを作る必要があるため、パフォーマンスを現実に低下させます。
膨大なデータを扱うアプリケーションでは、より低レベルの DAO や データベース API を使うのが良い選択でしょう。
最後にもう一つ大事なことですが、SELECT クエリで LIMIT を使ってください。 最後にもう一つ大事なことですが、SELECT クエリで LIMIT を使ってください。
こうすることで、大量のデータが返されて、PHP のために確保されたメモリを使い尽くすということがなくなります。 こうすることで、大量のデータが返されて、PHP のために確保されたメモリを使い尽くすということがなくなります。
### asArray を使う ## プレーンな配列を使う <span id="using-arrays"></span>
読み出し専用のページにおいて、メモリと処理時間を節約する良い方法に、アクティブレコードの `asArray` メソッドを使うという方法がありま [アクティブレコード](db-active-record.md) は非常に使い勝手のよいものですが、データベースから大量のデータを取得する必要がある場合は、プレーンな配列を使うほどには効率的ではありません
そういう場合は、アクティブレコードを使ってデータを取得する際に `asArray()` を呼んで、取得したデータがかさばるアクティブレコードのオブジェクトではなく配列として表現されるようにすることを考慮するのが良いでしょう。
例えば、
```php ```php
class PostController extends Controller class PostController extends Controller
{ {
public function actionIndex() public function actionIndex()
{ {
$posts = Post::find()->orderBy('id DESC')->limit(100)->asArray()->all(); $posts = Post::find()->limit(100)->asArray()->all();
return $this->render('index', ['posts' => $posts]); return $this->render('index', ['posts' => $posts]);
} }
} }
``` ```
ビューにおいて`$posts` の個々のレコードのフィールドを配列としてアクセスしなければなりません 上記において、`$posts` は、テーブル行の配列としてデータを代入されることになりま
各行はプレーンな配列になります。
`$i` 番目の行の `title` カラムにアクセスするためには、`$posts[$i]['title']` という式を使うことが出来ます。
```php クエリを構築するのに [DAO](db-dao.md) を使って、データをプレーンな配列に取得することも出来ます。
foreach ($posts as $post) {
echo $post['title'] . "<br>";
}
```
`asArray` が指定されていなくても配列記法を使用してフィールドにアクセスすることが出来ますが、その場合は AR オブジェクトを扱っていることに注意してください。
### Composer オートローダを最適化する ## Composer オートローダを最適化する
全体としてのパフォーマンスを改善するために、`composer dumpautoload -o` を実行して、Composer のオートローダを最適化することが出来ます。 全体としてのパフォーマンスを改善するために、`composer dumpautoload -o` を実行して、Composer のオートローダを最適化することが出来ます。
### バックグラウンドでデータを処理する ## バックグラウンドでデータを処理する
ユーザのリクエストに素早く応答したい場合、リクエストの重い部分は、それについて即座にレスポンスを返す必要がなければ、後から処理することが出来ます。 ユーザのリクエストに素早く応答したい場合、リクエストの重い部分は、それについて即座にレスポンスを返す必要がなければ、後から処理することが出来ます。
@ -216,19 +165,19 @@ foreach ($posts as $post) {
このソリューションでたいていの場合は OK ですが、一つ大きな欠点があります。 このソリューションでたいていの場合は OK ですが、一つ大きな欠点があります。
データベースを検索するまでは処理すべきデータの有無を知ることが出来ません。 データベースを検索するまでは処理すべきデータの有無を知ることが出来ません。
そのため、データベースをかなり頻繁に検索するか、または、処理の間に若干の遅延を生じさせるかのどちらかになります。 そのため、データベースをかなり頻繁に検索するか、または、データの作成と処理の間に若干の遅延を生じさせるかのどちらかになります。
この問題は、キューやジョブサーバ (RabbitMQ、ActiveMQ、Amazon SQS、その他いろいろ) によって解決することが出来ます。 この問題は、キューやジョブサーバ (RabbitMQ、ActiveMQ、Amazon SQS、その他いろいろ) によって解決することが出来ます。
この場合は、持続的ストレージにデータを書き込む代りに、キューやジョブサーバによって提供される API を通じてデータをキューに入れます。 この場合は、持続的ストレージにデータを書き込む代りに、キューやジョブサーバによって提供される API を通じてデータをキューに入れます。
処理はたいていはジョブハンドラのクラスに渡されます。 処理はたいていはジョブハンドラのクラスに渡されます。
キューに入れられたジョブは、先行するジョブが全て完了した直後に実行されます。 キューに入れられたジョブは、先行するジョブが全て完了した直後に実行されます。
### 何をしても効果がない場合 ## 何をしても効果がない場合
何をしても効果がない場合は、何がパフォーマンスの問題を解決するかについての思い込みを排することです。 何をしても効果がない場合は、何がパフォーマンスの問題を解決するかについての思い込みを排することです。
代りに、いつでも、何かを変更する前にはコードをプロファイルしてください。 代りに、いつでも、何かを変更する前にはコードをプロファイルしてください。
次のツールが役に立つでしょう。 次のツールが役に立つでしょう。
- [Yii のデバッグツールバーとデバッガ](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md) - [Yii のデバッグツールバーとデバッガ](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide-ja/README.md)
- [XDebug プロファイラ](http://xdebug.org/docs/profiler) - [XDebug プロファイラ](http://xdebug.org/docs/profiler)
- [XHProf](http://www.php.net/manual/en/book.xhprof.php) - [XHProf](http://www.php.net/manual/ja/book.xhprof.php)